Toggle 是一个水平方向扩张型的视图,垂直方向则不扩张。
Toggle 是一个可以打开或关闭的开关。像其他控件一样,你需要把它绑定到一个变量上,这个变量被传递到 Toggle 的初始化器中。然后需要做的是改变这个绑定变量的值来改变 Toggle 的状态,使其开启或关闭。或者读取绑定变量的值来查看 Toggle 当前处于什么状态。
// 简单文字开关
Toggle("Night Mode", isOn: $isToggleOn)
// SwiftUI 中同一段代码在不同设备上可以产生不同的 UI 。例如以上代码对于 iOS 和 iPadOS,Toggle 会渲染成开关;而在 macOS 会渲染成单选框。SwiftUI 的美妙之处是你可以针对所有 Apple 平台复用大部分的代码,无需修改。
// 宣告一個状态变量來储存目前开关的设定
@State private var showCheckInOnly = false
Toggle(isOn: $showCheckInOnly) { ... }
// 一种写法:是把 Toggle 的 Label 当作闭包视图,这样可以在里面写比较复杂的视图作为 Toggle 的左侧视图
Toggle(isOn: $showCheckInOnly) {
Text("开关的Label")
}
Toggle(isOn: $showCheckInOnly) {
VStack {
Text("Enable Dark Mode")
Text("开关的Label")
Image(systemName: "moon")
}
}
// 另一种简单的写法,不需要视图闭包,直接设置 Label 文字
Toggle("Show welcome message", isOn: $showGreeting)
// 在这种写法里,如果把字符串设置为空,会发现开关左侧仍然预留了一点的空间。如果想彻底隐藏,需要用到修饰符
Toggle("", isOn: $isToggleOn)
.labelsHidden()
SwiftUI 中内置的 toggleStyle
切换样式包括:
// 使用 toggleStyle 修饰符还可以自定义开关的颜色
Toggle("Show welcome message", isOn: $showGreeting)
.toggleStyle(SwitchToggleStyle(tint: .red))
// 如果您的目标平台是 iOS 15 或更高版本,则可以通过指定 .toggleStyle(.button) 将开关配置为显示为按钮
// 在此模式下,按钮在其状态打开时翻转其色调颜色:
Toggle("Filter", isOn: $isOn)
.toggleStyle(.button)
.tint(.mint)
<aside> 💡
toggleStyle
不能用 accentColor
修改颜色,应该用 .tint()
修饰符更改颜色。
</aside>
SwiftUI 提供了 ToggleStyle
协议来自定义 Toggle
开关的外观和工作方式。任何符合此协议的结构都必须实现 makeBody()
方法,该方法可以按照您的需要呈现 Toggle
,并且您将同时提供用于切换的标签和 isOn
绑定,您可以翻转它来调整切换。
重要提示:当您自定义 Toggle
开关时,您需要自己以某种方式切换打开状态,SwiftUI 不会为您做这件事。
以下演示自定义 Toggle
样式,这里使用按钮来翻转打开状态,然后添加自定义标签来显示该状态。我没有使用像标准 iOS Toggle
这样的移动圆圈,而是将此显示为两个 SF 符号之一:
struct CheckToggleStyle: ToggleStyle {
func makeBody(configuration: Configuration) ->some View {
Button {
configuration.isOn.toggle()
} label: {
Label {
configuration.label
} icon: {
Image(systemName: configuration.isOn ? "checkmark.circle.fill" : "circle")
.foregroundStyle(configuration.isOn ? Color.accentColor : .secondary)
.accessibility(label: Text(configuration.isOn ? "Checked" : "Unchecked"))
.imageScale(.large)
}
}
.buttonStyle(.plain)
}
}
// An example view showing the style in action
struct ContentView: View {
@State private var isOn = false
var body:some View {
Toggle("Switch Me", isOn: $isOn)
.toggleStyle(CheckToggleStyle())
}
}
该功能在 Xcode 中无法预览。
从 iOS 16 开始,还可以将 Toggle
绑定到布尔数组,这在您想要同时启用或禁用多个值时很有帮助。例如,我们可以编写一些代码来让用户订阅单个新闻通讯,或者通过一个开关来切换所有新闻通讯:
struct EmailList: Identifiable {
var id: String
var isSubscribed = false
}
struct ContentView: View {
@State var lists = [
EmailList(id: "Monthly Updates", isSubscribed: true),
EmailList(id: "News Flashes", isSubscribed: true),
EmailList(id: "Special Offers", isSubscribed: true)
]
var body: some View {
Form {
Section {
ForEach($lists) { $list in
Toggle(list.id, isOn: $list.isSubscribed)
}
}
// 源是输入数组,绑定该数组的某个键路径(也就是一组布尔值)
Section {
Toggle("Subscribe to all", sources: $lists, isOn: \\.isSubscribed)
}
}
}
}