zmkhtr/SwiftUIViewFinder
GitHub: zmkhtr/SwiftUIInspector
SwiftUIViewFinder 是一个仅用于调试的 Swift Package,能在运行时自动识别并以非交互式 overlay 展示当前 SwiftUI 视图的 struct 名称,帮助开发者追踪导航与标签切换过程中的视图层级。
Stars: 1 | Forks: 0
# SwiftUIViewFinder
SwiftUIViewFinder 是一个仅用于调试的 Swift package,它能在运行时识别当前的 SwiftUI view,并绘制一个包含其 struct 名称的非交互式 overlay。
只需在 `App.init()` 中启用一次即可。随后,ViewFinder 会自动跟踪标签切换、导航 push、隐藏标签的目标页面以及全屏展示,无需在整个应用中添加修饰符。
## 截图
| 选中的标签 | 隐藏标签栏的导航 push | 全屏展示 |
| --- | --- | --- |
|
|
|
|
overlay 窗口会将所有触摸事件透传给应用。系统 sheets(包括 `FamilyActivityPicker`)会暂时隐藏 overlay,以确保其保持完全可交互的状态。
## 安装
使用 Swift Package Manager 添加该 package:
```
dependencies: [
.package(
url: "https://github.com/zmkhtr/SwiftUIViewFinder.git",
from: "0.4.32"
)
]
```
然后将 `ViewFinder` product 添加到应用 target 中。
## 快速开始
在 SwiftUI 创建根视图图之前启用 ViewFinder:
```
import SwiftUI
import ViewFinder
@main
struct MyApp: App {
init() {
ViewFinder.enable(mode: .overlayAndLogs)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
```
这一次调用足以应对导航 push 和全屏展示。
对于 `TabView`,只需为每个标签注册一次根组件。ViewFinder 会自动读取选中的 UIKit 标签:
```
ViewFinder.enable(
mode: .overlayAndLogs,
tabComponents: [
HomeScreen.self,
SearchScreen.self,
SettingsScreen.self,
]
)
```
全局工作流不需要 `.enableViewFinder(...)` 或 `.viewFinderComponent(...)` 修饰符。
## 输出模式
```
ViewFinder.enable(mode: .overlay)
ViewFinder.enable(mode: .logs)
ViewFinder.enable(mode: .overlayAndLogs)
ViewFinder.disable()
```
Overlay 样式:
```
ViewFinder.enable(
mode: .overlayAndLogs,
overlayStyle: .detailed
)
```
该 overlay 被刻意设计为非交互式,并使用了独立的透传窗口。它根据轻量级的 UIKit 导航状态进行更新,仅在可见的导航结构发生变化时才执行更深度的 SwiftUI 检查。
## 可选的显式检查
原有的显式 API 仍可用于研究和精确的源码标记。
标记特定组件:
```
HomeScreen()
.viewFinderComponent()
```
检查具体的根值:
```
ViewFinder.enable(mode: .logs)
let report = ViewFinder.inspect(RootView())
print(report.formatted())
```
不安全的 body 评估仅适用于不依赖 SwiftUI 管理的 environment 或 dynamic properties 的受控研究视图:
```
ViewFinder.enable(mode: .logs)
let report = ViewFinder.inspect(RootView())
print(report.formatted())
```
## 支持的行为
- 从 `App.init()` 进行一次性全局设置
- 使用已注册的标签组件类型跟踪选中的 `TabView` 根视图
- `NavigationView` 和 navigation-controller 的 push
- 隐藏标签栏的 pushed 目标页面
- SwiftUI `fullScreenCover` 展示
- 不阻塞应用交互的透传 overlay
- 自动隐藏系统展示和 sheet 展示
- 基于变更的日志记录和缓存的 overlay 渲染
## 运行测试
```
swift test
xcodebuild test \
-scheme SwiftUIViewFinder-Package \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro'
```
## 限制
- 这是基于私有运行时、仅用于调试的研究软件。
- 私有的 SwiftUI API 可能会在不同的 iOS 和 Xcode 版本中发生变化。
- 目前需要注册标签根类型才能可靠地跟踪 `TabView` 选择。
- SwiftUI 可能会抹除复杂容器内部的组件边界。
- 精确的源文件和行号信息需要使用 `.viewFinderComponent()`。
- 对于复杂的视图图,overlay 可能会包含嘈杂或重叠的标签。
## 文档
- [研究发现](Docs/Research.md)
- [架构](Docs/Architecture.md)
- [疑难解答](Docs/Troubleshooting.md)
- [贡献指南](CONTRIBUTING.md)
## 许可证
MIT
|
|
|
overlay 窗口会将所有触摸事件透传给应用。系统 sheets(包括 `FamilyActivityPicker`)会暂时隐藏 overlay,以确保其保持完全可交互的状态。
## 安装
使用 Swift Package Manager 添加该 package:
```
dependencies: [
.package(
url: "https://github.com/zmkhtr/SwiftUIViewFinder.git",
from: "0.4.32"
)
]
```
然后将 `ViewFinder` product 添加到应用 target 中。
## 快速开始
在 SwiftUI 创建根视图图之前启用 ViewFinder:
```
import SwiftUI
import ViewFinder
@main
struct MyApp: App {
init() {
ViewFinder.enable(mode: .overlayAndLogs)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
```
这一次调用足以应对导航 push 和全屏展示。
对于 `TabView`,只需为每个标签注册一次根组件。ViewFinder 会自动读取选中的 UIKit 标签:
```
ViewFinder.enable(
mode: .overlayAndLogs,
tabComponents: [
HomeScreen.self,
SearchScreen.self,
SettingsScreen.self,
]
)
```
全局工作流不需要 `.enableViewFinder(...)` 或 `.viewFinderComponent(...)` 修饰符。
## 输出模式
```
ViewFinder.enable(mode: .overlay)
ViewFinder.enable(mode: .logs)
ViewFinder.enable(mode: .overlayAndLogs)
ViewFinder.disable()
```
Overlay 样式:
```
ViewFinder.enable(
mode: .overlayAndLogs,
overlayStyle: .detailed
)
```
该 overlay 被刻意设计为非交互式,并使用了独立的透传窗口。它根据轻量级的 UIKit 导航状态进行更新,仅在可见的导航结构发生变化时才执行更深度的 SwiftUI 检查。
## 可选的显式检查
原有的显式 API 仍可用于研究和精确的源码标记。
标记特定组件:
```
HomeScreen()
.viewFinderComponent()
```
检查具体的根值:
```
ViewFinder.enable(mode: .logs)
let report = ViewFinder.inspect(RootView())
print(report.formatted())
```
不安全的 body 评估仅适用于不依赖 SwiftUI 管理的 environment 或 dynamic properties 的受控研究视图:
```
ViewFinder.enable(mode: .logs)
let report = ViewFinder.inspect(RootView())
print(report.formatted())
```
## 支持的行为
- 从 `App.init()` 进行一次性全局设置
- 使用已注册的标签组件类型跟踪选中的 `TabView` 根视图
- `NavigationView` 和 navigation-controller 的 push
- 隐藏标签栏的 pushed 目标页面
- SwiftUI `fullScreenCover` 展示
- 不阻塞应用交互的透传 overlay
- 自动隐藏系统展示和 sheet 展示
- 基于变更的日志记录和缓存的 overlay 渲染
## 运行测试
```
swift test
xcodebuild test \
-scheme SwiftUIViewFinder-Package \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro'
```
## 限制
- 这是基于私有运行时、仅用于调试的研究软件。
- 私有的 SwiftUI API 可能会在不同的 iOS 和 Xcode 版本中发生变化。
- 目前需要注册标签根类型才能可靠地跟踪 `TabView` 选择。
- SwiftUI 可能会抹除复杂容器内部的组件边界。
- 精确的源文件和行号信息需要使用 `.viewFinderComponent()`。
- 对于复杂的视图图,overlay 可能会包含嘈杂或重叠的标签。
## 文档
- [研究发现](Docs/Research.md)
- [架构](Docs/Architecture.md)
- [疑难解答](Docs/Troubleshooting.md)
- [贡献指南](CONTRIBUTING.md)
## 许可证
MIT标签:iOS开发, Swift, SwiftUI, UI组件, 运行时检测