SwiftUI 如何按下圆形按钮打开设备选择菜单?
数据小许
结论
按下自定义圆形按钮显示设备菜单时,可以用 Menu 替换 .menu 样式的 Picker,并将圆形图标视图设为 Menu 的 label。选中菜单项后,更新 selectedDeviceID;选择“Don’t record microphone”时,将它设为 nil。
现有的 DevicePickerButton 已经把自定义圆形视图用作 Picker 的标签。如果想用另一种自定义按钮打开菜单,可以改用 Menu。SwiftUI 没有公开接口可让普通 Button 直接触发 Picker 自带的菜单。
用 Menu 替换 Picker
下面的写法保留设备列表和不录制麦克风选项,并继续用 pickerLabel 设置菜单按钮的外观:
var body: some View {
Menu {
if !devices.isEmpty {
Section("Devices") {
ForEach(devices, id: \.uniqueID) { device in
Button {
selectedDeviceID = device.uniqueID
} label: {
Text(device.localizedName)
}
}
}
}
Section {
Button("Don't record microphone") {
selectedDeviceID = nil
}
}
} label: {
pickerLabel
}
.menuStyle(.borderlessButton)
}
pickerLabel 可以沿用现有实现,包括 Circle 背景、悬停状态、图标和阴影。视图也可以继续根据当前选择显示不同图标:
private var currentIcon: String {
selectedDeviceID != nil ? icon : disabledIcon
}
选择设备后,selectedDeviceID 会更新。选择“Don’t record microphone”后,它会变为 nil,currentIcon 也会切换到 disabledIcon。
注意事项
Menu 会响应标签视图的点击并显示菜单,因此不需要再将它包在 Button 中。.borderlessButton 可以减少菜单控件额外的按钮外观。如果项目使用的 macOS 或 SwiftUI 版本不支持该样式,可以先移除这一行,再检查自定义标签的显示效果。
示例假设设备列表和 selectedDeviceID 的绑定已由现有视图提供。这里通过 Menu 创建自定义菜单入口,没有使用特定系统版本的额外菜单 API。
备注:内容仅供参考。
