Swift and SwiftUI tutorials for Swift Developers

How to Detect Screenshots in an iOS App Using SwiftUI

Screenshots are a core feature of iOS, but in many applications they can represent a privacy, security, or content-control issue. Banking apps, messaging apps, education platforms, and streaming services often need to know when a user has taken a screenshot so they can react accordingly: show a warning, hide sensitive data, or log an event.

In this tutorial you will learn how to detect when a user takes a screenshot in a SwiftUI-based iOS app using native iOS APIs, Xcode, and UIKit integration.

You will learn:

  • How iOS screenshot detection works
  • How to use UIApplication.userDidTakeScreenshotNotification
  • How to integrate it into SwiftUI
  • How to display alerts or run actions
  • How to hide sensitive information
  • Best practices and limitations

This tutorial is designed for beginner-to-intermediate developers building apps with SwiftUI.


🧠 Why Detect Screenshots?

Apple does not allow apps to block screenshots (for privacy and accessibility reasons), but it does allow you to detect when a screenshot happens.

Real-world use cases include:

  • Banking apps → show warnings
  • Messaging apps → notify the other user
  • Learning apps → prevent content sharing
  • Healthcare apps → protect personal data
  • Enterprise apps → track data leaks

SwiftUI does not provide a direct API for this, but UIKit does — and we can easily bridge the two.


🧩 How Screenshot Detection Works

iOS posts a system notification whenever the user takes a screenshot:

UIApplication.userDidTakeScreenshotNotification

When the user presses the hardware buttons (Power + Volume), the system sends this notification through NotificationCenter.

Our job is to:

  1. Subscribe to the notification
  2. Run code when it fires
  3. Integrate it into SwiftUI

🛠 Step 1 – Create a SwiftUI Project in Xcode

Open Xcode and create a new project:

  • Template: iOS App
  • Interface: SwiftUI
  • Language: Swift

Name it something like:
ScreenshotDetector


📡 Step 2 – Listen for Screenshot Notifications

UIKit sends a notification when a screenshot occurs:

NotificationCenter.default.addObserver(
    forName: UIApplication.userDidTakeScreenshotNotification,
    object: nil,
    queue: .main
) { notification in
    print("User took a screenshot")
}

But in SwiftUI we want a clean, reactive approach.


🔗 Step 3 – Create a Screenshot Detector

We create an observable class that listens for screenshots.

import SwiftUI
import UIKit

class ScreenshotDetector: ObservableObject {
    
    @Published var didTakeScreenshot = false
    
    init() {
        NotificationCenter.default.addObserver(
            forName: UIApplication.userDidTakeScreenshotNotification,
            object: nil,
            queue: .main
        ) { _ in
            self.didTakeScreenshot = true
        }
    }
}

This class updates a published property whenever a screenshot is detected.


🧱 Step 4 – Use It in SwiftUI

Now we integrate it into a SwiftUI view.

struct ContentView: View {
    
    @StateObject private var screenshotDetector = ScreenshotDetector()
    @State private var showAlert = false
    
    var body: some View {
        VStack(spacing: 20) {
            Text("Confidential Information")
                .font(.title)
            
            Text("Account number: 1234 5678 9012")
                .font(.headline)
                .foregroundColor(.red)
        }
        .padding()
        .onChange(of: screenshotDetector.didTakeScreenshot) { newValue in
            if newValue {
                showAlert = true
                screenshotDetector.didTakeScreenshot = false
            }
        }
        .alert("Screenshot detected",
               isPresented: $showAlert) {
            Button("OK", role: .cancel) { }
        } message: {
            Text("You have taken a screenshot. This action has been logged.")
        }
    }
}

Now when the user takes a screenshot, an alert appears.


🔐 Step 5 – Hide Sensitive Content After a Screenshot

A common pattern is hiding data once a screenshot is taken.

@State private var hideData = false

Then:

.onChange(of: screenshotDetector.didTakeScreenshot) { _ in
    hideData = true
}

And in the UI:

if hideData {
    Text("Content hidden for security reasons")
        .foregroundColor(.gray)
} else {
    Text("Account number: 1234 5678 9012")
        .foregroundColor(.red)
}

This doesn’t stop the screenshot, but prevents further exposure.


🧪 Step 6 – Test on a Real Device

⚠️ Screenshot detection does not work correctly in the simulator.
You must test on a real iPhone.

Press:
Side button + Volume Up

The alert should appear instantly.


🛡 Step 7 – Prevent Screenshots Using a Secure View Trick

Apple doesn’t allow screenshot blocking, but there is a workaround using secure UIKit views.

We can wrap SwiftUI content inside a secure UITextField:

struct SecureView<Content: View>: UIViewRepresentable {
    
    let content: Content
    
    func makeUIView(context: Context) -> UIView {
        let textField = UITextField()
        textField.isSecureTextEntry = true
        
        let hosting = UIHostingController(rootView: content)
        hosting.view.translatesAutoresizingMaskIntoConstraints = false
        
        textField.addSubview(hosting.view)
        
        NSLayoutConstraint.activate([
            hosting.view.topAnchor.constraint(equalTo: textField.topAnchor),
            hosting.view.bottomAnchor.constraint(equalTo: textField.bottomAnchor),
            hosting.view.leadingAnchor.constraint(equalTo: textField.leadingAnchor),
            hosting.view.trailingAnchor.constraint(equalTo: textField.trailingAnchor)
        ])
        
        return textField
    }
    
    func updateUIView(_ uiView: UIView, context: Context) { }
}

Usage:

SecureView {
    Text("Ultra-confidential content")
        .font(.title)
}

This causes iOS to render black boxes instead of your UI in screenshots.


⚠️ Technical and Legal Limitations

Apple requires that:

  • You cannot block screenshots
  • You cannot punish users for taking them
  • You can only react or protect content

Also:

  • Screen recording is harder to detect
  • Notifications arrive after the screenshot is taken

🧩 Real-World Use Cases

App typeRecommended action
BankingHide data + alert
MessagingNotify server
EducationShow warning
StreamingLog the event
HealthcareSecure view

🧠 Best Practices

  • Inform users in your privacy policy
  • Avoid excessive alerts
  • Use SecureView only for sensitive screens
  • Log events if required

🏁 Conclusion

Detecting screenshots in a SwiftUI iOS app is easy thanks to UIKit system notifications. With just a few lines of code, you can:

  • Detect screenshots
  • Show alerts
  • Hide sensitive data
  • Protect secure views

Although you cannot prevent screenshots entirely, you can control how your app responds — which is critical for modern apps that handle private or protected content.

With SwiftUI and Xcode, implementing this is clean, powerful, and fully compliant with Apple’s platform rules.

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

How to use Rich Text Editing with TextView and AttributedString in SwiftUI

Related Posts