使用 iOS 选择器、菜单和操作进行设计
Design with iOS pickers, menus and actions
2020年6月23日
一句话判断
iOS 14 重新定义了选择器、菜单和操作交互的 UI 范式——如果你还在用 Action Sheet 和 PickerView 做”选择”类交互,这场 Session 会告诉你为什么该换成 Menu 和 DatePicker 的新模式。
这场 Session 讲了什么
iOS 14 对多个交互组件进行了设计更新,Session 详细介绍了 Date Picker(日期选择器)、Color Picker(颜色选择器)、Context Menu(上下文菜单)和 Action 的新设计规范。这些变化的共同主题是”减少干扰、保持上下文”。
Date Picker 迎来了最大的变化。以前的全屏滚轮式日期选择器被替换为紧凑的 inline 样式——一个看起来像普通文本框的控件,点击后展开为日历视图或滚轮。这个设计变化的原因是全屏选择器打断了用户的操作流——选个日期要覆盖整个屏幕,太重了。新的 compact 样式只占用一行空间,展开后也只在当前视图上方浮层展示,不影响页面其他内容。
Color Picker 是全新的系统组件,提供了统一的颜色选择体验:包含网格色板、滑块和吸管工具。如果你的应用需要用户选择颜色,直接用系统的 UIColorPickerViewController,它已经处理了不同的色彩空间(sRGB、Display P3)和无障碍支持。
Context Menu(长按菜单)获得了增强,支持嵌套子菜单和更大的预览图。Session 展示了如何通过 UIContextMenuInteraction 创建多级菜单结构。
值得深挖的点
Compact Date Picker 的交互哲学
新的 compact date picker 体现了 Apple 的”轻量化交互”设计哲学:用户期望的操作应该用最少的界面面积完成。选择一个日期不应该是一个”事件”,而应该像选择一个下拉选项一样自然。compact 模式下,日历视图从按钮位置弹出,选择后自动收回。这种”点即选”的体验比以前”打开新页面 -> 滚轮选择 -> 点确认”流畅得多。
Menu 替代 Action Sheet 的趋势
iOS 14 中,越来越多的”选择”场景推荐使用 Menu 替代 Action Sheet。Menu 是一个轻量级的浮层菜单,从触发点弹出,不遮挡全部屏幕。Action Sheet 则是底部弹出的模态面板,需要用户明确操作才能关闭。Session 建议:2-5 个选项的场景用 Menu,需要用户确认的重要操作(如删除)用 Action Sheet。
代码片段
import SwiftUI
// 新的 Date Picker 样式
struct DatePickerExample: View {
@State private var selectedDate = Date()
@State private var birthDate = Date()
var body: some View {
Form {
// Compact 样式(默认)—— 一行空间,点击展开
DatePicker(
"选择日期",
selection: $selectedDate,
displayedComponents: [.date]
)
// 自动使用 GraphicalDatePickerStyle
// Graphical 样式——直接展示日历
DatePicker(
"生日",
selection: $birthDate,
in: ...Date(), // 不能选择未来日期
displayedComponents: [.date]
)
.datePickerStyle(.graphical)
// Wheel 样式(经典滚轮)
DatePicker(
"时间",
selection: $selectedDate,
displayedComponents: [.hourAndMinute]
)
.datePickerStyle(.wheel)
}
}
}
// 新的 Color Picker
import SwiftUI
struct ColorPickerExample: View {
@State private var selectedColor: Color = .blue
@State private var showColorPicker = false
var body: some View {
VStack(spacing: 20) {
// SwiftUI 原生颜色选择器
ColorPicker(
"选择颜色",
selection: $selectedColor,
supportsOpacity: true // 支持透明度调节
)
// 展示选中颜色的效果
RoundedRectangle(cornerRadius: 12)
.fill(selectedColor)
.frame(width: 200, height: 100)
.overlay(
Text("预览")
.foregroundColor(.white)
.bold()
)
}
.padding()
}
}
// Context Menu 与嵌套菜单
import SwiftUI
struct MenuExample: View {
@State private var selectedSort = "默认排序"
var body: some View {
List {
// Menu 按钮(轻量级替代 Action Sheet)
Menu {
// 嵌套子菜单
Menu("排序方式") {
Button("按名称") { selectedSort = "名称" }
Button("按日期") { selectedSort = "日期" }
Button("按大小") { selectedSort = "大小" }
}
Divider()
Button("刷新数据") {
refreshData()
}
Button("全选") {
selectAll()
}
Divider()
// 危险操作用红色文字
Button(role: .destructive) {
deleteAll()
} label: {
Label("删除全部", systemImage: "trash")
}
} label: {
Label("操作", systemImage: "ellipsis.circle")
}
Text("当前排序: \(selectedSort)")
}
.contextMenu {
// 长按触发的 Context Menu
Button {
copyItem()
} label: {
Label("复制", systemImage: "doc.on.doc")
}
Button {
shareItem()
} label: {
Label("分享", systemImage: "square.and.arrow.up")
}
Divider()
Button(role: .destructive) {
deleteItem()
} label: {
Label("删除", systemImage: "trash")
}
}
}
func refreshData() {}
func selectAll() {}
func deleteAll() {}
func copyItem() {}
func shareItem() {}
func deleteItem() {}
}
最佳实践
- 新项目默认使用 compact date picker,只在需要”沉浸式”日期选择场景(如日历应用)时使用 graphical 样式
- 2-5 个选项的”选择”场景用 Menu,超过 5 个选项考虑用 List 或专门的筛选页
- 使用系统 Color Picker 而非自建颜色选择器——系统组件自动适配 Dark Mode 和无障碍
- Context Menu 中使用图标(SF Symbols)增强可识别性,每个选项配一个图标
- 危险操作(删除、重置)使用
.destructiverole,系统会自动用红色文字标记
还有什么值得关注
- compact date picker 在 iOS 14 中是
DatePicker的默认样式,不需要额外配置 - Color Picker 支持 Display P3 广色域,在设计类应用中特别有用
- SwiftUI 的
Menu在 iPad 上以 popover 形式展示,在 iPhone 上以 action sheet 形式展示,系统自动适配