用样式构建界面
Build interfaces with style
2021年6月10日
一句话判断
SwiftUI 在 iOS 15 中补上了样式系统这块拼图——ButtonRole、controlSize、listStyle 等新 API 让你不用写自定义修饰符就能获得平台一致的视觉效果。
这场 Session 讲了什么
Session 聚焦 SwiftUI 的样式和外观定制能力。iOS 15 引入了一套语义化的样式 API,让你用更少的代码实现更一致的界面。核心思路是:描述你想要什么效果(“这是一个破坏性按钮”),而不是描述怎么做(“把这个按钮变成红色”)。
具体新增包括 ButtonRole(区分 destructive 和 cancel 等语义角色)、controlSize(.mini、.small、.regular 三档控制组件大小)、prompt 参数(给 TextField 加提示文本)、以及改进的 listStyle 在不同平台上的自动适配。这些 API 的共同特点是:你只指定语义,平台负责具体渲染。
Session 还展示了 SwiftUI 在 macOS 和 watchOS 上的样式适配能力。同一个 List 视图在不同平台上自动呈现不同的外观,而不需要你写条件编译。
值得深挖的点
语义化样式 vs 硬编码样式
ButtonRole.destructive 不是简单地把按钮文字变红。它会根据上下文智能调整:在普通上下文中是红色文字,在确认弹窗的上下文中可能表现为红色填充按钮,在 watchOS 上可能是不同的图标。这个设计哲学贯穿了整个 iOS 15 的 SwiftUI 更新——你告诉系统意图,系统决定呈现。这和 UIKit 的 UIAlertAction.Style.destructive 一脉相承,但应用范围更广。
controlSize 的级联效果
controlSize 不是只影响单个组件。设置在容器上时,它会级联到所有子组件。一个 .controlSize(.small) 放在 Form 上,里面的 TextField、Picker、Button 全部变小。这解决了之前每个组件都要单独设置大小的痛点。但要注意,某些组件在 .mini 尺寸下可能省略标题文字,你需要测试实际效果。
代码片段
使用 ButtonRole 创建语义化按钮
// 破坏性操作按钮,系统自动选择合适的红色样式
Button("删除全部", role: .destructive) {
deleteAll()
}
// 取消按钮,系统自动选择非强调样式
Button("取消", role: .cancel) {
dismiss()
}
// 在 confirmationDialog 中组合使用
.confirmationDialog("确认删除?", isPresented: $showConfirm) {
Button("删除", role: .destructive) { deleteItem() }
Button("取消", role: .cancel) { }
}
controlSize 控制组件大小
// 在容器级别设置,级联到所有子组件
VStack {
TextField("搜索", text: $searchText)
Button("搜索") { performSearch() }
}
.controlSize(.small)
// 单独设置某个组件
Button("查看详情") { showDetail() }
.controlSize(.large)
给 TextField 添加 prompt
// prompt 在输入框为空时显示灰色的辅助文字
TextField("邮箱地址", text: $email, prompt: Text("请输入有效邮箱"))
.textInputAutocapitalization(.never)
.keyboardType(.emailAddress)
// SecureField 也支持 prompt
SecureField("密码", text: $password, prompt: Text("至少 8 位字符"))
最佳实践
新项目: 用语义化 API 代替硬编码样式。按钮用 role 而不是 .foregroundColor(.red)。控件大小用 controlSize 而不是 .frame(height:)。这样你的 App 会自动跟随未来的系统设计规范。
已有项目: 检查现有代码中的 .foregroundColor(.red) 和 .accentColor(.red) 用在按钮上的地方,替换为 ButtonRole.destructive。把手动设置高度的控件改为 controlSize。这些改动不需要大规模重构,可以逐个替换。
还有什么值得关注
- SwiftUI 的
keyboardShortcut在 macOS 上支持更多系统快捷键。 - iOS 15 的
submitLabel参数控制键盘上的 return 键文字(如”搜索”、“完成”)。 textFieldStyle新增.roundedBorder,可以直接获得带圆角边框的输入框样式。