Highlight
SwiftUI 在 iOS 17、iPadOS 17 和 macOS Sonoma 中新增
inspector修饰符,让开发者用一行代码为应用添加自适应的详情面板:在宽屏下显示为右侧边栏,在紧凑尺寸下自动转为可调整大小的 Sheet,并支持程序化控制列宽和展示状态。
核心内容
Inspector 是什么
你在 Keynote 里一定见过右侧面板:选中一个形状,右侧弹出格式设置。在 Shortcuts 里,右侧显示的是可用动作库。这些就是 Inspector。
(00:31)
以前开发者要自己用 NavigationSplitView 或手动管理 Sheet 来实现类似效果。代码复杂不说,还要自己处理不同尺寸下的适配。iOS 17 开始,SwiftUI 提供了原生的 inspector 修饰符,一行代码搞定。
(01:51)
放置位置决定外观
Inspector 的行为取决于它在视图层级中的位置。放在 NavigationStack 内部时,它显示在导航栏下方;放在外部时,它占据整列高度。
(06:01)
Toolbar 的位置也有讲究。在 Inspector 的 view builder 里声明的 toolbar 会显示在 Inspector 上方的工具栏区域;在外部声明的则显示在主内容的工具栏里。当 Inspector 以 Sheet 形式呈现时,内部声明的 toolbar 会跟着进入 Sheet。
(06:44)
Sheet 展示自定义
iOS 16.4 引入的 Sheet 自定义修饰符可以和 Inspector 组合使用。你可以设置背景材质、定义多个高度档位、控制背景内容的交互。
(09:37)
比如你想让 Inspector 在紧凑模式下以 Sheet 呈现时,小高度不遮挡背景内容,但展开到中等高度后显示遮罩。这只需要两个修饰符就能实现。
(11:58)
详细内容
基础用法
struct ContentView: View {
@State private var state = AppState()
@State private var presented = true
var body: some View {
AnimalTable(state: $state)
.inspector(isPresented: $presented) {
AnimalInspectorForm(animal: $state.binding())
.inspectorColumnWidth(
min: 200, ideal: 300, max: 400)
.toolbar {
Spacer()
Button {
presented.toggle()
} label: {
Label("Toggle Inspector", systemImage: "info.circle")
}
}
}
}
}
(03:54)
关键点:
.inspector(isPresented:)接收一个Binding<Bool>控制展示状态- Inspector 的内容在 trailing closure 中定义
.inspectorColumnWidth(min:ideal:max:)设置列宽范围,ideal是首次启动时的宽度,用户调整后会持久化- Inspector 内部声明的
.toolbar会显示在 Inspector 上方的工具栏区域 - Inspector 默认使用 grouped form 样式,不需要手动设置
在 NavigationStack 内部使用
struct Example1: View {
@State private var state = AppState()
var body: some View {
NavigationStack {
AnimalTable(state: $state)
.inspector(isPresented: $state.inspectorPresented) {
AnimalInspectorForm(animal: $state.binding())
}
.toolbar {
Button {
state.inspectorPresented.toggle()
} label: {
Label("Toggle Inspector", systemImage: "info.circle")
}
}
}
}
}
(07:14)
关键点:
- Inspector 放在
NavigationStack内部时,显示在导航栏下方(under toolbar 样式) - Toolbar 在主内容上声明,显示在导航栈的工具栏里
- 在紧凑尺寸下,Inspector 以 Sheet 呈现,toolbar 按钮仍留在主内容工具栏
在 NavigationStack 外部使用
struct Example2: View {
@State private var state = AppState()
var body: some View {
NavigationStack {
AnimalTable(state: $state)
}
.inspector(isPresented: $state.inspectorPresented) {
AnimalInspectorForm(animal: $state.binding())
.toolbar {
ToolbarItem(placement: .principal) {
HStack {
Button {
} label: {
Image(systemName: "rectangle.and.pencil.and.ellipsis")
}
Button {
} label: {
Image(systemName: "pawprint.circle")
}
}
}
}
}
}
}
(07:55)
关键点:
- Inspector 放在
NavigationStack外部时,占据整列高度(full height 样式) - Toolbar 在 Inspector 的 view builder 里声明,显示在 Inspector 上方的专用工具栏区域
- 在紧凑尺寸下以 Sheet 呈现时,toolbar 内容会跟着进入 Sheet
NavigationSplitView 中的使用
// 方式一:放在 detail column 内部
NavigationSplitView {
Sidebar()
} detail: {
AnimalTable()
.inspector(presented: $isPresented) {
AnimalInspectorForm()
}
}
// 方式二:放在 NavigationSplitView 外部
NavigationSplitView {
Sidebar()
} detail: {
AnimalTable()
}
.inspector(presented: $isPresented) {
AnimalInspectorForm()
}
(08:56)
关键点:
- 在
NavigationSplitView中,Inspector 可以放在 detail column 内部或整个 split view 外部 - 两种放置方式都有效,选择取决于你希望 Inspector 与哪个层级的导航结构关联
结合 Sheet 展示自定义
.sheet(item: $nibbledFruit) { fruit in
FruitNibbleBulletin(fruit: fruit)
.presentationBackground(.thinMaterial)
.presentationDetents([.height(200), .medium, .large])
.presentationBackgroundInteraction(.enabled(upThrough: .height(200)))
}
(09:49)
关键点:
.presentationBackground(.thinMaterial)设置 Sheet 背景为半透明材质,底层内容可以隐约透出.presentationDetents([.height(200), .medium, .large])定义三个高度档位.presentationBackgroundInteraction(.enabled(upThrough: .height(200)))允许在高度为 200 时与背景内容交互,超过这个高度后显示遮罩
这些修饰符同样适用于 Inspector 在紧凑尺寸下的 Sheet 呈现:
.inspector(presented: $state.inspectorPresented) {
AnimalInspectorForm(animal: $state.binding())
.presentationDetents([.height(200), .medium, .large])
.presentationBackgroundInteraction(.enabled(upThrough: .height(200)))
}
(11:58)
核心启发
1. 给任何选择型界面加上 Inspector
如果你的应用有表格、列表或网格,用户选中一行后需要查看或编辑详情,用 .inspector 替代手动管理的 Sheet 或 Split View。它自动适配 iPhone、iPad 和 Mac,不需要写平台判断代码。入口是在选中视图上添加 .inspector(isPresented:) 修饰符。
2. 用 Inspector 做辅助面板
像 Shortcuts 那样,Inspector 可以展示与主内容相关的工具库或属性面板。比如一个代码编辑器,主区域是代码,Inspector 显示文件大纲或属性检查器。入口是把工具内容放在 .inspector 的 trailing closure 中,用 inspectorColumnWidth 控制默认宽度。
3. 组合 Sheet 自定义实现分层交互
在 iPhone 上,Inspector 以 Sheet 呈现。你可以用 .presentationDetents 和 .presentationBackgroundInteraction 实现分层交互:小高度时用户可以继续操作主内容,展开后才进入专注编辑模式。入口是给 Inspector 内容加上 presentation 修饰符。
4. 利用 toolbar 位置控制按钮归属
Inspector 相关的操作按钮(如关闭、更多选项)放在 Inspector 的 view builder 里声明,这样它们在 Sheet 模式下会出现在 Sheet 的工具栏中。主内容的操作按钮放在主视图上声明。入口是仔细规划 .toolbar 修饰符的位置。
关联 Session
- SwiftUI essentials — SwiftUI 基础结构 API 总览
- Build programmatic UI with Xcode Previews — 新 Preview API 支持 UIKit 和 AppKit
- What’s new in SwiftUI — SwiftUI 年度新特性汇总
- Meet SwiftUI for spatial computing — visionOS 上的 SwiftUI 适配
评论
GitHub Issues · utterances