Skip to content

abdorizak/ScreenshotShield

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ScreenshotShield

Swift Platform License

Protect sensitive UIKit content from screenshots and screen recordings.

ScreenshotShield is a lightweight Swift package that helps you protect sensitive content in your iOS app from being captured in screenshots or screen recordings. Perfect for banking apps, password managers, confidential documents, and any app handling sensitive data.

Features

  • Prevent sensitive content from appearing in screenshots
  • Detect and respond to screen recording/mirroring
  • Easy-to-use UIKit components
  • Customizable blocked overlay
  • Supports iOS 13+
  • Zero dependencies

Installation

Swift Package Manager

Add ScreenshotShield to your project using Xcode:

  1. Go to File → Add Package Dependencies...
  2. Enter the repository URL:
    https://github.com/abdorizak/ScreenshotShield.git
    
  3. Select your version rules and add to your target

Or add it to your Package.swift:

dependencies: [
    .package(url: "https://github.com/abdorizak/ScreenshotShield.git", from: "1.0.0")
]

Quick Start

import ScreenshotShield

class ConfidentialViewController: UIViewController {

    private let secureContainer = SecureContainerView()
    private let blockedOverlay = ScreenshotBlockedOverlay()

    override func viewDidLoad() {
        super.viewDidLoad()

        // 1. Add overlay FIRST (it will be behind)
        view.addSubview(blockedOverlay)

        // 2. Add secure container ON TOP
        view.addSubview(secureContainer)

        // 3. Layout both views
        blockedOverlay.translatesAutoresizingMaskIntoConstraints = false
        secureContainer.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            blockedOverlay.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            blockedOverlay.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            blockedOverlay.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            blockedOverlay.bottomAnchor.constraint(equalTo: view.bottomAnchor),

            secureContainer.topAnchor.constraint(equalTo: view.topAnchor),
            secureContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            secureContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            secureContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])

        // 4. Add your sensitive content to the secure container
        setupSecureContent()
    }

    private func setupSecureContent() {
        let content = secureContainer.contentView
        content.backgroundColor = .systemBackground

        let secretLabel = UILabel()
        secretLabel.text = "API Key: sk_live_abc123xyz"
        secretLabel.font = .monospacedSystemFont(ofSize: 16, weight: .regular)

        content.addSubview(secretLabel)
        secretLabel.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            secretLabel.centerXAnchor.constraint(equalTo: content.centerXAnchor),
            secretLabel.centerYAnchor.constraint(equalTo: content.centerYAnchor),
        ])
    }
}

How It Works

ScreenshotShield leverages iOS's secure text field mechanism:

  1. Normal App Usage: Your content is fully visible and interactive
  2. Screenshot Taken: iOS automatically blanks the secure content, revealing the overlay behind
  3. Screen Recording: The library detects recording and can notify you to take action
┌─────────────────────────────────┐
│     ScreenshotBlockedOverlay    │  ← Behind (visible in screenshots)
├─────────────────────────────────┤
│       SecureContainerView       │  ← On top (blanked in screenshots)
│   ┌─────────────────────────┐   │
│   │      contentView        │   │
│   │   (your sensitive UI)   │   │
│   └─────────────────────────┘   │
└─────────────────────────────────┘

Components

SecureContainerView

The main container that protects its content from screenshots.

let secureContainer = SecureContainerView()

// Add content to the contentView
secureContainer.contentView.addSubview(mySecretView)

// Toggle protection on/off
secureContainer.isProtectionEnabled = true

// Listen for screen capture changes
secureContainer.onScreenCaptureStateChanged = { isCaptured in
    if isCaptured {
        print("Screen is being recorded!")
    }
}

// Check current capture state
if secureContainer.isScreenBeingCaptured {
    // Handle screen recording
}

ScreenshotBlockedOverlay

A pre-built overlay to display when content is blocked.

// Default styling
let overlay = ScreenshotBlockedOverlay()

// Custom styling
let customOverlay = ScreenshotBlockedOverlay(
    icon: UIImage(systemName: "lock.shield.fill"),
    title: "Protected Content",
    message: "Screenshots are not allowed for security reasons.",
    backgroundColor: .systemBackground
)

// Modify after creation
overlay.icon = UIImage(systemName: "exclamationmark.triangle.fill")
overlay.iconTintColor = .systemOrange
overlay.title = "Access Restricted"
overlay.message = "Please disable screen recording to continue."
overlay.iconSize = 80

ScreenshotShield (Utility)

Static utilities for screen capture detection.

// Check if screen is being captured
if ScreenshotShield.isScreenBeingCaptured {
    // Handle accordingly
}

// Observe screen capture changes globally
let observer = ScreenshotShield.observeScreenCapture { isCaptured in
    print("Screen capture state: \(isCaptured)")
}

// Remove observer when done
ScreenshotShield.removeObserver(observer)

Advanced Usage

Toggle Protection with a Switch

class SettingsViewController: UIViewController {

    private let secureContainer = SecureContainerView()
    private let blockedOverlay = ScreenshotBlockedOverlay()
    private let protectionSwitch = UISwitch()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Setup views...

        protectionSwitch.isOn = true
        protectionSwitch.addTarget(self, action: #selector(toggleProtection), for: .valueChanged)
    }

    @objc private func toggleProtection() {
        secureContainer.isProtectionEnabled = protectionSwitch.isOn
        blockedOverlay.isHidden = !protectionSwitch.isOn
    }
}

Handle Screen Recording

class BankingViewController: UIViewController {

    private let secureContainer = SecureContainerView()
    private let blockedOverlay = ScreenshotBlockedOverlay()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Setup views...

        // Handle screen recording
        secureContainer.onScreenCaptureStateChanged = { [weak self] isCaptured in
            self?.handleScreenCapture(isCaptured)
        }
    }

    private func handleScreenCapture(_ isCaptured: Bool) {
        if isCaptured {
            // Bring overlay to front during recording
            view.bringSubviewToFront(blockedOverlay)
            blockedOverlay.isHidden = false
        } else {
            // Send overlay back behind container
            view.sendSubviewToBack(blockedOverlay)
        }
    }
}

Requirements

  • iOS 13.0+
  • Swift 5.9+
  • Xcode 15.0+

Limitations

  • This protection relies on iOS's internal secure text field behavior
  • The behavior may vary slightly across different iOS versions
  • Screen recording detection notifies after recording starts (cannot prevent)
  • Not a guarantee against all forms of capture (e.g., external cameras)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

ScreenshotShield is available under the MIT license. See the LICENSE file for more info.

Author

Abdul Razakabdorizak.dev


Made with love for the UIKit community.

About

Lightweight Swift package to prevent screenshot capture in iOS apps

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages