SwiftUI 中的 Inspector:展示内容细节的新方式
Inspectors in SwiftUI: Discover the details
2023年6月5日
一句话判断
SwiftUI 的 inspector 修饰符为 macOS 和 iOS/iPadOS 提供了一个统一的”详情面板”抽象——在大屏上表现为尾随侧栏,在紧凑尺寸上自动适配为可调整大小的 Sheet。
这场 Session 讲了什么
Session 介绍了 SwiftUI 新增的 inspector 修饰符,它用于展示选中内容的详细信息。类似 Keynote 中右侧的格式检查器、Shortcuts 中的操作库面板。
基本用法。inspector 修饰符接受一个 Bool 绑定(控制显示/隐藏)和一个 ViewBuilder(检查器的内容)。检查器默认使用 GroupedFormStyle,不需要手动设置表单样式。
列宽控制。inspectorColumnWidth 修饰符可以设置最小、理想和最大宽度。理想宽度是首次启动时的尺寸,用户手动调整后系统会自动持久化。
上下文适配。检查器会根据放置位置自动选择样式:放在 NavigationStack 内时使用 “under toolbar” 样式(工具栏在检查器上方);放在导航结构外时使用 “full height” 样式(检查器占据完整高度)。在紧凑尺寸类(如 iPhone 竖屏)上,检查器自动适配为可调整大小的 Sheet。
工具栏位置。在检查器 ViewBuilder 内声明的工具栏项目会出现在检查器上方的工具栏中;在外部声明的则出现在主导航工具栏中。这个规则在检查器适配为 Sheet 时也适用——内部工具栏项目会跟随 Sheet。
Session 还简要介绍了 iOS 16.4 引入的 Sheet 展示自定义修饰符:presentationBackground、presentationContentInteraction、presentationCornerRadius 等。
值得深挖的点
inspector 与 NavigationSplitView 的配合:如果你在 NavigationSplitView 中使用 inspector,应该把 inspector 放在 detail 列的 ViewBuilder 中,或者完全放在导航结构外部。放在 sidebar 列中会导致意外的布局行为。
full height vs under toolbar 的选择:这个选择不是你来做的,而是由 inspector 修饰符的位置决定的。理解这个规则对设计正确的布局层级至关重要。
presentation 修饰符的通用性:presentationBackground、presentationCornerRadius 等修饰符不仅适用于 Sheet,也适用于 Popover 和 Inspector。这是 SwiftUI 统一展示定制 API 的一部分。
代码片段
添加一个基本的 Inspector:
struct AnimalTableView: View {
@State private var selectedAnimal: Animal?
@State private var isInspectorPresented = false
var body: some View {
AnimalTable(selectedAnimal: $selectedAnimal)
.inspector(isPresented: $isInspectorPresented) {
// 检查器内容
if let animal = selectedAnimal {
AnimalInspectorForm(animal: animal)
.inspectorColumnWidth(
min: 200, ideal: 300, max: 400
)
// 在检查器内部的工具栏项目
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button("完成") {
isInspectorPresented = false
}
}
}
}
}
// 在外部的工具栏项目出现在主导航工具栏
.toolbar {
ToolbarItem {
Button {
isInspectorPresented.toggle()
} label: {
Label("检查", systemImage: "info.circle")
}
}
}
}
}
自定义 Sheet 的展示效果:
.sheet(isPresented: $showBulletin) {
NibbleBulletinView(bulletin: bulletin)
.presentationBackground(.thinMaterial)
.presentationCornerRadius(20)
// 允许背景内容交互
.presentationContentInteraction(.scrolls)
}
最佳实践
- 检查器放在
NavigationStack内部或外部有不同效果,根据设计意图选择正确位置 - 使用
inspectorColumnWidth控制列宽,理想宽度作为首次展示尺寸 - 在检查器 ViewBuilder 内声明的工具栏项目会出现在检查器上方
- compact 尺寸类上检查器自动变成 Sheet,无需额外适配
- 如果在
NavigationSplitView中使用,放在 detail 列或导航结构外部
还有什么值得关注
- Inspector 在 visionOS 上的表现和交互方式
presentationContentInteraction对手势冲突的影响- Inspector 与 Sheet/Popover 的交互优先级
- 自定义 presentation detents 与 Inspector 的组合使用