XRay
Visual debugging tool for Apple platforms — inspect view hierarchies at runtime with color-coded overlays
Install / Use
/learn @ShawnBaek/XRayREADME
XRay
Visual debugging tool for Apple platforms — inspect view hierarchies at runtime with color-coded overlays.
XRay shows all view hierarchies in UIKit without using Xcode's Debug View Hierarchy. Take a screenshot to trigger the overlay.
<img width="878" alt="XRay debug view overlay" src="https://user-images.githubusercontent.com/12643700/170850603-653ee787-a388-4d46-8ae5-adce39ab22ce.png">Status: Stable — feature complete. No active development needed.
Demo
https://user-images.githubusercontent.com/12643700/170850041-0c024526-5d14-49c7-9ab5-7e09fe5e2397.mp4
Features
- Recursively traverses entire view hierarchy
- Color-coded labels by view type:
- Red (center): ViewController
- Blue (trailing bottom): Custom View
- Black (leading top): Standard View
- Complementary color borders for maximum contrast
- Two filter modes:
.all(full hierarchy) and.customClass(custom views only) - Debug-only — safely wrapped in
#if DEBUG
Requirements
- Swift 5.6+
- iOS 11+
Installation
Swift Package Manager
Add to your Package.swift:
dependencies: [
.package(url: "https://github.com/ShawnBaek/XRay.git", from: "1.0.2")
]
Or in Xcode: File > Add Package Dependencies and enter:
https://github.com/ShawnBaek/XRay.git
Usage
1. Add Screenshot Notification Listener
In your AppDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
#if DEBUG
NotificationCenter.default.addObserver(
self, selector: #selector(screenshotTaken),
name: UIApplication.userDidTakeScreenshotNotification, object: nil
)
#endif
return true
}
2. Handle the Screenshot Event
#if DEBUG
@objc func screenshotTaken() {
guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let keyWindow = scene.keyWindow,
let topViewController = keyWindow.topViewController() else {
return
}
let xray = XRay(rootViewController: topViewController)
xray.captureXray(classNameOption: .all)
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5)) {
xray.removeXray()
}
}
#endif
ClassNameOption
.all — Shows all view hierarchies
<img width="487" src="https://user-images.githubusercontent.com/12643700/170850418-e3e73dea-8ad3-4f4e-8153-dad98a1e937b.png">
.customClass — Shows custom views only
<img width="487" src="https://user-images.githubusercontent.com/12643700/170850346-b9466c75-e66e-4742-b1e3-93a16b2351b4.png">
License
MIT License. See LICENSE for details.
Author
Shawn Baek — GitHub · shawn@shawnbaek.com
Related Skills
node-connect
347.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
347.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
