A Swift framework to hide UIView/NSView/CALayer, and SwiftUI views on iOS 18 and newer, from being captured when taking screenshots.
| Coverage | Workflow | Matrix | Status |
|---|---|---|---|
| Package public API | package.yml |
iOS 18.5 with Xcode 16.4 & iOS 26.2 with Xcode 26.3 | |
| Package public API with SPI interfaces | package_interface.yml |
iOS 18.5 with Xcode 16.4 & iOS 26.2 with Xcode 26.3 | |
| UIKit example UI tests | example_uikit.yml |
iOS 18.5 with Xcode 16.4 & iOS 26.2 with Xcode 26.3 | |
| SwiftUI example UI tests | example_swiftui.yml |
iOS 18.5 with Xcode 16.4 & iOS 26.2 with Xcode 26.3 | |
| OpenSwiftUI example UI tests | example_openswiftui.yml |
iOS 18.5 with Xcode 16.4 & iOS 26.2 with Xcode 26.3 |
In your Package.swift file, add the following dependency to your dependencies argument:
.package(url: "https://github.com/Kyle-Ye/ScreenShieldKit.git", from: "0.2.0"),Then add the dependency to any targets you've declared in your manifest:
.target(
name: "MyTarget",
dependencies: [
.product(name: "ScreenShieldKit", package: "ScreenShieldKit"),
]
),Instead of wrapping your view in a secure UITextField or ScreenShieldView,
you can just directly call the hiddenFromCapture(_:) API on your view or layer.
import ScreenShieldKit
let view = UIView(frame: .zero)
view.hiddenFromCapture(true)
// Restore the behavior
view.hiddenFromCapture(false)For SwiftUI on iOS 18, macOS 15, tvOS 18, watchOS 11, and visionOS 2 or newer:
import ScreenShieldKit
import SwiftUI
Text("Sensitive content")
.hiddenFromCapture()For OpenSwiftUI, enable the package trait. The dependency uses the OpenSwiftUI-spm binary package from version 0.18.1.
swift build --traits OpenSwiftUIimport OpenSwiftUI
import ScreenShieldKit
Text("Sensitive content")
.hiddenFromCapture()AppKit support is best-effort. The current implementation uses the same private
layer update mask path as UIKit, but that has been observed not to hide NSView
contents from macOS system captures reliably.
To build against the local SPI interface shims instead of ScreenShieldKit's
fallback declarations, set SCREENSHIELDKIT_USE_SPI_INTERFACES=1 before
building.
SCREENSHIELDKIT_USE_SPI_INTERFACES=1 swift buildThe example apps are managed by Tuist:
cd Example
mise trust --yes
mise install
mise exec -- tuist install
mise exec -- tuist generate --no-openAvailable schemes:
UIKitExample: UIKit demo and the target app for UI tests.AppKitExample: macOS AppKit demo.SwiftUIExample: SwiftUI demo for iOS and macOS.OpenSwiftUIExample: OpenSwiftUI demo for iOS and macOS.
Detailed documentation for ScreenShieldKit can be found on GitHub Pages.
See LICENSE file - MIT
- @NSAntoine for the CALayer capture hiding write-up: https://nsantoine.dev/posts/CALayerCaptureHiding
- @Kyle-Ye for the SwiftUI capture hiding notes: https://kyleye.top/posts/swiftui-hidden-from-capture
