A Swift package for capturing screenshots of iOS UI — including full-page scrollable content and stable captures that wait for rendering to settle.
- iOS 13.0+
- Swift 6.2+
Because this package targets iOS (UIKit-only), pass the iOS Simulator SDK and triple explicitly:
swift build \
--sdk "$(xcrun --sdk iphonesimulator --show-sdk-path)" \
--triple arm64-apple-ios16.0-simulatorOr with xcodebuild:
xcodebuild build -scheme ScreenshotKit -destination "generic/platform=iOS Simulator"Add ScreenshotKit to your Package.swift:
dependencies: [
.package(url: "https://github.com/your-org/swift-ScreenshotKit", from: "1.0.0")
]Or add it in Xcode via File → Add Package Dependencies.
Automatically captures the full scrollable content if a UIScrollView is present in the top view controller, otherwise falls back to a window snapshot.
import ScreenshotKit
let image = await UIApplication.shared.largestScreenshot(resize: true)Captures a window snapshot that polls until two consecutive frames match, ensuring animations and async rendering have settled before capturing.
let image = await UIApplication.shared.stableSnapShot()Captures the full scrollable content of the top view controller's scroll view, waiting for rendering to settle before compositing the full-page image.
let image = await UIApplication.shared.stableScrollViewSnapshot()let image = await myScrollView.stableScrollViewSnapshot()let image = myView.snapshot(resize: true)let vc = UIApplication.shared.topViewControllerlet window = UIApplication.shared.firstWindowlet scrollView = view.subviewOfType(UIScrollView.self)Retrieves the app's splash screen images from the system's SplashBoard cache. Returns an empty array if unavailable.
let splashImages = UIApplication.shared.splashScreensThe stableSnapShot() and stableScrollViewSnapshot() methods use a polling strategy:
- Capture two consecutive screenshots with a 100ms delay between them.
- Compare their PNG data.
- If they differ, wait another 100ms and capture again.
- Repeat up to 6 times until two consecutive captures match.
This ensures the UI has finished rendering (including async image loads, animations, etc.) before the final screenshot is taken.
UIScrollView.stableScrollViewSnapshot() composes a full-page image of the entire scrollable content by:
- Waiting for stable rendering (polling loop above).
- Temporarily zeroing out content insets and offsets.
- Iterating through vertical offsets equal to the viewport height.
- Drawing each visible section into a
CGContextwith the correct translation. - Restoring original insets and offset via
defer.
The resulting image always uses a scale of 1.0 (device-independent pixels) for predictable output dimensions.
| API | Description |
|---|---|
firstWindow: UIWindow? |
The key window from the first connected window scene. |
topViewController: UIViewController? |
The topmost presented view controller, traversing nav, tab, and modal stacks. |
topViewController(base:) |
Recursive helper for traversing the view controller hierarchy. |
largestScreenshot(resize:) async -> UIImage? |
Best-effort screenshot: full scroll view content or window snapshot. iOS 16+. |
stableSnapShot() async -> UIImage? |
Window snapshot that waits for rendering to settle. |
stableScrollViewSnapshot() async -> UIImage? |
Full-page scroll view capture that waits for rendering to settle. |
splashScreens: [UIImage] |
Splash screen images from the system SplashBoard cache. |
| API | Description |
|---|---|
stableScrollViewSnapshot() async -> UIImage? |
Full-page capture of scrollable content, polling until stable. |
| API | Description |
|---|---|
snapshot(resize:) -> UIImage? |
Snapshot of the view and its subview hierarchy. |
subviewOfType<T>(_:) -> T? |
Recursive depth-first search for a subview of a given type. |
MIT