If you’ve ever used a banking app or an authenticator app, you’ve probably noticed a unique security feature: you can’t take a screenshot of sensitive information. This isn’t just a UX decision — it’s a serious security measure to prevent secrets like OTPs, card numbers, or recovery codes from being captured and stored in the device gallery (or worse, shared).
As iOS developers, we often face the challenge of implementing similar restrictions. But how do you actually prevent screenshots in iOS? Unfortunately, iOS doesn’t give us a single “one-liner” API for this. Instead, we need to combine multiple techniques, depending on the context.
In this blog, we’ll go beyond the basics and look at three major patterns used in real-world production apps:
- Window-level screenshot prevention (like StackOverflow discussions often suggest)
- View/UITextField-level protection
- Advanced hybrid approaches (custom rendering, blur overlays, and dynamic snapshot interception)
Let’s dive in.
1. Window-level Prevention (Global Blanket)
The most straightforward approach is to block screenshots at the window level. iOS triggers a notification whenever the system captures a snapshot of your app (for multitasking previews, App Switcher, or screenshots).
You can subscribe to this event:
private func makeSecure(window: UIWindow) {
let field = UITextField()
let view = UIView(frame: CGRect(x: 0, y: 0, width: field.frame.size.width, height: field.frame.size.height))
let image = UIImageView(image: UIImage(named: "Screen_Shot_Prevented"))
image.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
field.isSecureTextEntry = true
window.addSubview(field)
view.addSubview(image)
window.layer.superlayer?.addSublayer(field.layer)
field.layer.sublayers?.last?.addSublayer(window.layer)
field.leftView = view
field.leftViewMode = .always
}Then, in your SceneDelegate or AppDelegate:
func sceneDidBecomeActive(_ scene: UIScene) {
// Apply screenshot prevention when scene becomes active
if let window = window, secureField == nil {
print("🔒 Applying screenshot prevention...")
makeSecure(window: window)
}
}This ensures that every system-generated snapshot (like App Switcher previews) shows only a blank or secure screen.
✅ Pros:
- Covers the entire app.
- No need to micromanage individual views.
❌ Cons:
- Heavy-handed — you lose flexibility.
- Doesn’t differentiate between sensitive and non-sensitive views.
This is why most apps combine this with more targeted approaches.
2. UITextField / View-level Protection
Sometimes, you only need to protect specific fields — like a PIN input, a credit card number, or a recovery code.
UIKit has a neat trick: if you set a text field’s isSecureTextEntry to true, iOS automatically prevents it from being included in screenshots and system snapshots.
let secureField = UITextField() secureField.isSecureTextEntry = true
This works not just for hiding characters with dots (••••), but also for excluding them from screenshots.
But what if you don’t want the dots (because you’re displaying OTP digits, for example)? One hack is to layer a UILabel on top of the UITextField and still set the field to secure:
let hiddenField = UITextField() hiddenField.isSecureTextEntry = true hiddenField.isUserInteractionEnabled = false hiddenField.isHidden = true
let displayLabel = UILabel() displayLabel.text = "123 456" // OTP shown
This way, the UITextField protects against screenshots, but your UILabel controls the display.
✅ Pros:
- Very precise — only affects sensitive fields.
- Zero performance overhead.
❌ Cons:
- Limited to
UITextField. - Needs hacks for non-standard UI.
3. Advanced Hybrid Approaches
Experienced apps (like authenticator apps) go beyond these basics. They use hybrid strategies that balance security and UX.
3.1 Blur Overlays on WillResignActive
When the app goes to the background (e.g., user switches apps), iOS takes a snapshot for the app switcher. We can intercept this and overlay a blur:
func sceneWillResignActive(_ scene: UIScene) {
if let window = (scene as? UIWindowScene)?.windows.first {
let blurEffect = UIBlurEffect(style: .light)
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = window.bounds
blurView.tag = 999
window.addSubview(blurView)
}
}func sceneDidBecomeActive(_ scene: UIScene) {
if let window = (scene as? UIWindowScene)?.windows.first {
window.viewWithTag(999)?.removeFromSuperview()
}
}Now the App Switcher preview shows only a blurred screen, but the actual app UI is untouched.
3.2 Custom Rendering for Sensitive Views
Some apps render sensitive content using Core Animation layers that never make it into system snapshots. For example:
class SecureLabel: UILabel {
override func draw(_ rect: CGRect) {
if let ctx = UIGraphicsGetCurrentContext() {
ctx.setFillColor(UIColor.clear.cgColor)
ctx.fill(rect)
}
super.draw(rect)
}
override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? {
return UIView() // prevents inclusion in snapshots
}
}This way, the label shows up normally on screen but disappears in screenshots.
3.3 Detecting Screenshots (Forensics)
iOS also broadcasts a notification whenever the user takes a screenshot:
NotificationCenter.default.addObserver(
forName: UIApplication.userDidTakeScreenshotNotification,
object: nil,
queue: .main
) { _ in
// Log, alert, or wipe sensitive info
print("⚠️ Screenshot detected!")
}You can’t prevent the screenshot itself, but you can react: log the event, mask sensitive data, or show a warning.
Conclusion
Screenshot prevention in iOS isn’t a one-size-fits-all problem. Depending on your use case, you might:
- Use window-level overrides to secure the whole app.
- Apply UITextField-level tricks for input fields.
- Implement hybrid solutions (blur overlays, custom rendering, screenshot detection) for maximum control.
That’s exactly how banking apps, authenticator apps, and other security-focused platforms build their protection layers.
👉 Pro tip: Don’t rely on a single approach. Combine multiple strategies depending on the sensitivity of the data.
With these patterns in your toolkit, you can design robust, screenshot-resistant iOS apps that would make even security teams applaud.