- Published on
- 5 min read
> Detecting When a Screenshot is Taken in SwiftUI
Detecting when users take screenshots can be useful for analytics, security alerts, or triggering specific behaviors in your app. iOS provides a notification that fires whenever a screenshot is captured, making this straightforward to implement.
Basic Screenshot Detection
iOS posts a userDidTakeScreenshotNotification through UIApplication whenever a screenshot is taken. You need to import UIKit and observe this notification:
import SwiftUI
import UIKit
struct ContentView: View {
var body: some View {
Text("Take a screenshot!")
.font(.title)
.onReceive(NotificationCenter.default.publisher(
for: UIApplication.userDidTakeScreenshotNotification
)) { _ in
print("Screenshot detected!")
// Handle screenshot event
}
}
}
Practical Use Case: Screenshot Analytics
Track when users screenshot content for analytics purposes:
import SwiftUI
import UIKit
struct AnalyticsView: View {
@State private var screenshotCount = 0
var body: some View {
VStack(spacing: 20) {
Text("Premium Content")
.font(.title)
Text("Screenshots taken: \(screenshotCount)")
.foregroundColor(.secondary)
Image(systemName: "photo.on.rectangle.angled")
.font(.system(size: 100))
.foregroundColor(.blue)
}
.onReceive(NotificationCenter.default.publisher(
for: UIApplication.userDidTakeScreenshotNotification
)) { _ in
screenshotCount += 1
logScreenshotEvent()
}
}
func logScreenshotEvent() {
// Send analytics event
print("User took screenshot at \(Date())")
// Analytics.logEvent("screenshot_taken", parameters: nil)
}
}
Screenshot Warning for Sensitive Content
Alert users when they screenshot sensitive information:
import SwiftUI
import UIKit
struct SensitiveContentView: View {
@State private var showWarning = false
var body: some View {
VStack {
Text("Confidential Information")
.font(.title)
.padding()
Text("Account Number: 1234-5678-9012")
.font(.system(.body, design: .monospaced))
.padding()
Text("DO NOT SHARE")
.foregroundColor(.red)
.font(.caption)
}
.onReceive(NotificationCenter.default.publisher(
for: UIApplication.userDidTakeScreenshotNotification
)) { _ in
showWarning = true
}
.alert("Screenshot Detected", isPresented: $showWarning) {
Button("OK", role: .cancel) { }
} message: {
Text("Please keep this information confidential and do not share screenshots.")
}
}
}
Using a View Modifier
Create a reusable modifier for screenshot detection:
import SwiftUI
import UIKit
struct ScreenshotDetector: ViewModifier {
let onScreenshot: () -> Void
func body(content: Content) -> some View {
content
.onReceive(NotificationCenter.default.publisher(
for: UIApplication.userDidTakeScreenshotNotification
)) { _ in
onScreenshot()
}
}
}
extension View {
func onScreenshot(perform action: @escaping () -> Void) -> some View {
modifier(ScreenshotDetector(onScreenshot: action))
}
}
// Usage
struct MyView: View {
var body: some View {
Text("Content")
.onScreenshot {
print("Screenshot taken!")
}
}
}
Screenshot with Context Tracking
Track which screen was screenshot:
import SwiftUI
import UIKit
struct ScreenTracker: View {
@State private var currentScreen = "Home"
var body: some View {
NavigationStack {
VStack {
Text("Welcome to \(currentScreen)")
.font(.title)
NavigationLink("Go to Details") {
DetailView(screenName: "Details")
}
}
.navigationTitle(currentScreen)
}
.onScreenshot {
logScreenshot(screen: currentScreen)
}
}
func logScreenshot(screen: String) {
print("Screenshot taken on screen: \(screen)")
// Send to analytics with context
}
}
struct DetailView: View {
let screenName: String
var body: some View {
Text("Details Screen")
.onScreenshot {
print("Screenshot taken on: \(screenName)")
}
}
}
Combining Detection with Prevention
Use screenshot detection alongside prevention for sensitive content:
import SwiftUI
import UIKit
struct BankingView: View {
@State private var showSecurityWarning = false
var body: some View {
VStack(spacing: 20) {
Text("Account Balance")
.font(.headline)
// This content should be protected from screenshots
Text("$10,234.56")
.font(.system(size: 48, weight: .bold))
.privacySensitive() // iOS 15+ hides from screenshots
}
.onScreenshot {
showSecurityWarning = true
// Log security event
logSecurityEvent("screenshot_attempt")
}
.alert("Security Notice", isPresented: $showSecurityWarning) {
Button("Understood", role: .cancel) { }
} message: {
Text("Screenshots of sensitive financial information have been detected. Please keep your account details private.")
}
}
func logSecurityEvent(_ event: String) {
// Log to security monitoring system
print("Security event: \(event)")
}
}
Observable Object Pattern
For app-wide screenshot monitoring:
import SwiftUI
import UIKit
import Combine
class ScreenshotMonitor: ObservableObject {
@Published var totalScreenshots = 0
@Published var lastScreenshotDate: Date?
private var cancellable: AnyCancellable?
init() {
cancellable = NotificationCenter.default
.publisher(for: UIApplication.userDidTakeScreenshotNotification)
.sink { [weak self] _ in
self?.handleScreenshot()
}
}
private func handleScreenshot() {
totalScreenshots += 1
lastScreenshotDate = Date()
// Send to analytics
print("Total screenshots: \(totalScreenshots)")
}
}
struct AppView: View {
@StateObject private var screenshotMonitor = ScreenshotMonitor()
var body: some View {
VStack {
Text("Screenshots Taken: \(screenshotMonitor.totalScreenshots)")
if let date = screenshotMonitor.lastScreenshotDate {
Text("Last screenshot: \(date.formatted())")
.font(.caption)
.foregroundColor(.secondary)
}
}
}
}
Important Notes
- The notification fires after the screenshot is already taken - you cannot prevent the screenshot from this notification alone
- For preventing screenshots of sensitive content, see Preventing Screenshot Capture in SwiftUI Views
- Screenshots taken while the app is in the background will still trigger the notification when the app returns to foreground
- This works for screenshots taken with physical buttons or AssistiveTouch, but not for screen recordings
- Remember to import
UIKitto accessUIApplicationnotifications
Testing
To test screenshot detection:
- Run your app on a physical device or simulator
- Take a screenshot (iPhone: Volume Up + Side button, Simulator: Cmd+S)
- Verify your handler is called
Screenshot detection is useful for analytics and security awareness, but remember that it cannot prevent screenshots from being taken. Combine it with the .privacySensitive() modifier or field-level security for truly sensitive content.
// Continue_Learning
Preventing Screenshot Capture in SwiftUI Views
Learn how to prevent users from taking screenshots of sensitive content in your SwiftUI app using field-level security and UIKit bridging for financial, medical, or private data protection.
Accessing the Camera Roll in SwiftUI
Learn how to access photos from the camera roll in SwiftUI, including required permissions, Info.plist configuration, and using PhotosPicker for iOS 16+ or UIImagePickerController for earlier versions.
SwiftUI vs UIKit: Which Should You Choose in 2026?
A practical guide to choosing between SwiftUI and UIKit in 2026, based on your project requirements, team experience, and the current state of both frameworks.
// Stay Updated
Get notified when I publish new tutorials on Swift, SwiftUI, and iOS development. No spam, unsubscribe anytime.