ViewMonitor: an in-app layout inspector for UIKit and SwiftUI
An in-app visual layout inspector for iOS. Inspect UIKit and SwiftUI views, frames, spacing, overlaps, insets, and properties on device.
At a glance
- What is it?
- ViewMonitor is a Swift package that puts a measurement overlay inside a running iOS app, so you can read frames, gaps and insets without opening Xcode's View Debugger. It is useful for design QA, and it has a hard boundary around what SwiftUI exposes.
- Who is it for?
- Adopt ViewMonitor if you do design QA on iOS and want frame, gap and inset numbers on a simulator or device without leaving the app, and if your SwiftUI work is mostly layout rather than styling. Do not adopt it if you need SwiftUI font, background, alpha or corner radius values, or if you want to scroll and inspect in the same pass, since measurement mode blocks touches from reaching the app.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 52 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What ViewMonitor measures inside a running iOS app
The problem it targets is narrow and recurring. A layout looks wrong on a device, and the fastest way to find out why is usually to attach Xcode's View Debugger or to guess at constraint values. ViewMonitor takes a different route: it adds an overlay to the app itself, and you tap elements to read their geometry. The README describes it as an in-app visual layout inspector, and the capabilities table splits cleanly by framework. Position and size are available for both UIKit and SwiftUI. Text content is available for UIKit labels and buttons, and for SwiftUI as published accessibility text. Background, alpha, corner radius, font family, font size and font color are listed as available for UIKit labels and button titles, and as not available for SwiftUI. The intended user is an iOS developer or designer doing layout QA, not someone profiling rendering performance. The README also frames a second use case: comparing a design specification with the implementation directly on a simulator or device.
How the overlay, selection and comparison flow works
ViewMonitor starts in two different ways depending on the framework. For SwiftUI, the README says to enable SwiftUI element detection in a debug build and attach a `.viewMonitor()` modifier to the root view. For UIKit, you call `ViewMonitor.start()` after the app has a window, and the README's example puts that call in `scene(_:willConnectTo:options:)`. After that, a ViewMonitor button appears in the top-right corner, and tapping it enters measurement mode.
The comparison mechanism is the part worth understanding. You select one element, then another. According to the README, the previous element gets a blue outline, the current element gets a red outline, and the info panel describes the relationship between them. If the frames are separated, the panel reports `gapX` and `gapY` as edge-to-edge spacing. If the frames intersect, it reports `overlapX` and `overlapY` per axis. If one frame contains the other, it reports `top`, `left`, `bottom` and `right` as inner insets. Because the numbers come from the frames in the running app, the same comparison works for UIKit-to-UIKit, SwiftUI-to-SwiftUI, and UIKit-to-SwiftUI pairs. That mixed case is the one Xcode's View Debugger handles least comfortably, and it is where ViewMonitor's value is clearest.
Measurement mode is deliberately intrusive. The README states that it blocks touches from reaching the app, which prevents accidental navigation, actions or scrolling. Overlay buttons stay at the positions captured when measurement started. Rotation and programmatic screen changes keep measurement mode on, re-scan the new screen, and clear the previous selection. The README's own instruction for interacting with the app is to turn measurement mode off, move to the desired state, then turn it on again. That is a real workflow constraint, not a footnote: you cannot scroll a list and inspect rows in the same pass.
Installing ViewMonitor with Swift Package Manager or CocoaPods
The package is distributed through Swift Package Manager and CocoaPods, and the README gives both routes. In Xcode, the instruction is to choose File > Add Package Dependencies and enter the repository URL. In `Package.swift`, the README shows a dependency entry with a `from: "2.0.0"` version requirement.
dependencies: [
.package(
url: "https://github.com/daisuke0131/ViewMonitor.git",
from: "2.0.0"
)
]The README does not print a CocoaPods `Podfile` line; it only states that the pod is published as `ViewMonitor` and links to cocoapods.org, so check the podspec for the exact version constraint you want. Requirements are listed as iOS 15.0+, Xcode 26.0+ and Swift 6.0+.
For a first real use in a SwiftUI app, the README's startup pattern enables element detection in the app initializer and attaches the root modifier.
import SwiftUI
import ViewMonitor
@main
struct MyApp: App {
init() {
ViewMonitor.enableSwiftUIElementDetection()
}
var body: some Scene {
WindowGroup {
ContentView()
.viewMonitor()
}
}
}Run the app, tap the ViewMonitor button in the top-right corner, then tap two elements in sequence. You should see a blue outline on the first, a red outline on the second, and a panel reporting `gapX` and `gapY`, `overlapX` and `overlapY`, or `top`, `left`, `bottom` and `right` depending on how the two frames relate. For a UIKit app, the equivalent first step is calling `ViewMonitor.start()` from the scene delegate after the window exists. The repository ships two examples, `Example/ViewMonitorSwiftUIExample` and `Example/ViewMonitorExample`, which the README says run on the simulator as-is. For a physical device, the README instructs you to create a git-ignored `Local.xcconfig` next to the example and set your Apple Developer Team ID:
echo 'DEVELOPMENT_TEAM = XXXXXXXXXX' > Example/ViewMonitorExample/Local.xcconfig
echo 'DEVELOPMENT_TEAM = XXXXXXXXXX' > Example/ViewMonitorSwiftUIExample/Local.xcconfigThe debug-only accessibility trick behind SwiftUI detection
The most interesting design decision in ViewMonitor is how it finds SwiftUI elements at all. SwiftUI does not expose a view tree the way UIKit does. What it does publish is an accessibility tree, and iOS builds that tree only while an accessibility client is active. The README explains that `ViewMonitor.enableSwiftUIElementDetection()` activates the tree from inside the process, so the overlay can find SwiftUI elements without VoiceOver or Accessibility Inspector attached. The helper relies on a private accessibility API. Consequently it is compiled into debug builds only. In release builds it is a no-op that returns `false`, and the README states the private symbol names are not included in the binary. That is a reasonable safety posture, and it also means SwiftUI inspection is not something you can leave switched on for a QA build you hand to someone else, unless you accept the private API risk yourself.
There is a fallback path: attach Xcode's Accessibility Inspector or enable VoiceOver, then reopen the screen. The README also says that if ViewMonitor finds SwiftUI content but no accessibility elements, the info panel displays instructions rather than failing silently. That is better than a blank overlay, though it puts the burden on the person holding the device to read and act on the panel.
Where ViewMonitor stops being the right tool
The SwiftUI limitations are the sharpest edge. Position, size, element type and published text are available; font, background, alpha and corner radius are not. If your bug is a wrong text color or a corner radius that does not match the spec, ViewMonitor cannot answer it on a SwiftUI screen, and the README's capability table says so directly. Two more SwiftUI behaviours matter in practice. Views using `.accessibilityElement(children: .combine)` are measured as one element, so a composed row reports as a single frame rather than its parts. Views using `.accessibilityHidden(true)` are not detected at all. Both follow from reading the accessibility tree rather than the view hierarchy, and both will surprise someone who expects the overlay to see everything on screen.
The measurement-mode touch blocking is the second limitation, and it is a workflow one rather than a correctness one. You cannot scroll, tap a button or trigger navigation while measuring. The README's prescribed loop is to leave measurement mode, reach the state you want, and re-enter it. For a long scrolling list where the interesting row is far down, that is a repeated cycle rather than a single inspection session. Also note that the README does not document any export, logging or snapshot format for the measurements. The numbers live in the on-device panel, so if you need to attach evidence to a bug report, capturing it is your problem, not the tool's.
ViewMonitor compared with Xcode's View Debugger and Accessibility Inspector
The obvious alternative is Xcode's View Debugger, and the difference is where the inspection runs. View Debugger pauses the app and reconstructs a 3D view hierarchy on the Mac, which gives you the full UIKit tree and lets you inspect properties that the app never exposes at runtime. ViewMonitor runs inside the app, keeps it live, and works on a physical device without a debugger session attached. It also spans UIKit and SwiftUI in a single comparison, which is the case the README highlights: a UIKit-to-SwiftUI pair where you want the edge-to-edge gap between them. View Debugger remains the stronger choice when you need the complete hierarchy, when you want to inspect a view that is not an accessibility element, or when you need to correlate a layout problem with Auto Layout constraint conflicts.
The second alternative is Xcode's Accessibility Inspector, which the README itself names as a fallback for activating the SwiftUI accessibility tree. Accessibility Inspector is built for auditing accessibility, not for layout measurement, and it does not give you the gap, overlap and containment inset vocabulary that ViewMonitor's info panel uses. If you already attach Accessibility Inspector during SwiftUI work, ViewMonitor's detection helper is doing something similar from inside the process, with the difference that its output is framed around geometry rather than accessibility semantics.
Maintenance, licensing and the cost of upgrading
The repository is not archived, and the last push was on 2026-08-09. The release list shows 2.4.0 and 2.3.0 both dated 2026-08-09, and 2.2.0 on 2026-08-06, so the recent cadence is dense rather than steady. There is a CHANGELOG.md at the repository root, which is the file to read before bumping a version. The README's `from: "2.0.0"` example means Swift Package Manager will pull any 2.x release, so a minor bump arrives without a deliberate decision on your part. Given that the SwiftUI detection helper is compiled into debug builds only, an upgrade that touches that helper cannot break a release build, but it can change what a debug build sees. That is worth a check in the examples before rolling it out to a team.
Licensing is MIT, per the LICENSE file and the badge in the README. MIT is permissive and places few obligations on how you redistribute the package, but the README's note that the SwiftUI helper relies on a private accessibility API is a separate question from the licence. A permissive licence does not make a private API acceptable to App Review, and the README's own answer is that the helper is debug-only and the private symbol names are absent from release binaries. Whether that is enough for your release process is a judgement for your team, not something the licence settles.
Editorial conclusion
Adopt ViewMonitor if you do design QA on iOS and want frame, gap and inset numbers on a simulator or device without leaving the app, and if your SwiftUI work is mostly layout rather than styling. Do not adopt it if you need SwiftUI font, background, alpha or corner radius values, or if you want to scroll and inspect in the same pass, since measurement mode blocks touches from reaching the app. Before wiring it into a project, verify the Swift 6.0, iOS 15.0 and Xcode 26.0 requirements against your toolchain, and decide where the debug-only SwiftUI detection call belongs in your app lifecycle.
Frequently asked questions
What is ViewMonitor and who is it for?
ViewMonitor is an in-app visual layout inspector for iOS that measures frames, spacing, insets and view properties in a running app. It is aimed at iOS developers and designers doing layout or design QA on a simulator or device.
How do I install ViewMonitor in an iOS project?
Add the package through Swift Package Manager using File > Add Package Dependencies in Xcode, or add a `.package(url:from:)` entry to `Package.swift` as the README shows. The README also states that ViewMonitor is available through CocoaPods, and lists iOS 15.0+, Xcode 26.0+ and Swift 6.0+ as requirements.
Why does ViewMonitor need SwiftUI element detection enabled in debug builds?
iOS builds the SwiftUI accessibility tree only while an accessibility client is active, so `ViewMonitor.enableSwiftUIElementDetection()` activates it from inside the process. The helper relies on a private accessibility API, so the README states it is compiled into debug builds only and is a no-op returning `false` in release builds.
Can ViewMonitor inspect SwiftUI font, background or corner radius values?
No. The README's capability table lists background, alpha, corner radius, font family, font size and font color as not available for SwiftUI. Position, size, element type and published accessibility text are available.
Why can I not scroll or tap buttons while measuring with ViewMonitor?
Measurement mode blocks touches from reaching the app to prevent accidental navigation, actions or scrolling. The README's instruction is to turn measurement mode off, move the app to the desired state, then turn it on again.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/daisuke0131-viewmonitor)