从选择器 SwiftUI 中取消选择项目
Deselecting item from a picker SwiftUI
我使用带有选择器的表单,一切正常(我可以从选择器中 select 一个元素),但我不能 deselect 它。是否存在从选择器中删除select 项目的方法?
谢谢!
Picker(selection: $model.countries, label: Text("country")) {
ForEach(model.countries, id: \.self) { country in
Text(country!.name)
.tag(country)
}
}
要取消选择,我们需要选择器值的可选存储,因此这里是一个可能方法的演示。
测试 Xcode 12.1 / iOS 14.1
struct ContentView: View {
@State private var value: Int?
var body: some View {
NavigationView {
Form {
let selected = Binding(
get: { self.value },
set: { self.value = [=10=] == self.value ? nil : [=10=] }
)
Picker("Select", selection: selected) {
ForEach(0...9, id: \.self) {
Text("\([=10=])").tag(Optional([=10=]))
}
}
}
}
}
}
首先,我们可以固定选择。它应该与标签的类型相匹配。给定的标签是 Country
,因此要在可能不选择任何内容的情况下进行选择,我们应该使用 Country?
作为 selection
类型。
它应该是这样的:
struct ContentView: View {
@ObservedObject private var model = Model()
@State private var selection: Country?
var body: some View {
NavigationView {
Form {
Picker(selection: $selection, label: Text("country")) {
ForEach(model.countries, id: \.self) { country in
Text(country!.name)
.tag(country)
}
}
Button("Clear") {
selection = nil
}
}
}
}
}
然后您只需将 selection
设置为 nil
,这是在按钮中完成的。您可以通过任意操作将 selection
设置为 nil
。
如果您的部署目标设置为 iOS 14 或更高 -- Apple 为 View 提供了一个内置的 onChange 扩展,您可以在其中使用标签取消选择您的行,它可以像这样使用(谢谢)
Picker(selection: $favoriteColor, label: Text("Color")) {
// ..
}
.onChange(of: favoriteColor) { print("Color tag: \([=10=])") }
通过阅读 this blog by Jim Dovey,我几乎了解了所有关于 SwiftUI 绑定(带有核心数据)的知识。剩下的就是一些研究和犯错误的许多小时的结合。
因此,当我结合 Jim 的技术在 SwiftUI Binding
上创建 Extensions
和 Asperi 的 时,我们最终会得到类似这样的东西...
public extension Binding where Value: Equatable {
init(_ source: Binding<Value>, deselectTo value: Value) {
self.init(get: { source.wrappedValue },
set: { source.wrappedValue = [=10=] == source.wrappedValue ? value : [=10=] }
)
}
}
然后可以像这样在整个代码中使用...
Picker("country", selection: Binding($selection, deselectTo: nil)) { ... }
或
Picker("country", selection: Binding($selection, deselectTo: someOtherValue)) { ... }
我使用带有选择器的表单,一切正常(我可以从选择器中 select 一个元素),但我不能 deselect 它。是否存在从选择器中删除select 项目的方法? 谢谢!
Picker(selection: $model.countries, label: Text("country")) {
ForEach(model.countries, id: \.self) { country in
Text(country!.name)
.tag(country)
}
}
要取消选择,我们需要选择器值的可选存储,因此这里是一个可能方法的演示。
测试 Xcode 12.1 / iOS 14.1
struct ContentView: View {
@State private var value: Int?
var body: some View {
NavigationView {
Form {
let selected = Binding(
get: { self.value },
set: { self.value = [=10=] == self.value ? nil : [=10=] }
)
Picker("Select", selection: selected) {
ForEach(0...9, id: \.self) {
Text("\([=10=])").tag(Optional([=10=]))
}
}
}
}
}
}
首先,我们可以固定选择。它应该与标签的类型相匹配。给定的标签是 Country
,因此要在可能不选择任何内容的情况下进行选择,我们应该使用 Country?
作为 selection
类型。
它应该是这样的:
struct ContentView: View {
@ObservedObject private var model = Model()
@State private var selection: Country?
var body: some View {
NavigationView {
Form {
Picker(selection: $selection, label: Text("country")) {
ForEach(model.countries, id: \.self) { country in
Text(country!.name)
.tag(country)
}
}
Button("Clear") {
selection = nil
}
}
}
}
}
然后您只需将 selection
设置为 nil
,这是在按钮中完成的。您可以通过任意操作将 selection
设置为 nil
。
如果您的部署目标设置为 iOS 14 或更高 -- Apple 为 View 提供了一个内置的 onChange 扩展,您可以在其中使用标签取消选择您的行,它可以像这样使用(谢谢)
Picker(selection: $favoriteColor, label: Text("Color")) {
// ..
}
.onChange(of: favoriteColor) { print("Color tag: \([=10=])") }
通过阅读 this blog by Jim Dovey,我几乎了解了所有关于 SwiftUI 绑定(带有核心数据)的知识。剩下的就是一些研究和犯错误的许多小时的结合。
因此,当我结合 Jim 的技术在 SwiftUI Binding
上创建 Extensions
和 Asperi 的
public extension Binding where Value: Equatable {
init(_ source: Binding<Value>, deselectTo value: Value) {
self.init(get: { source.wrappedValue },
set: { source.wrappedValue = [=10=] == source.wrappedValue ? value : [=10=] }
)
}
}
然后可以像这样在整个代码中使用...
Picker("country", selection: Binding($selection, deselectTo: nil)) { ... }
或
Picker("country", selection: Binding($selection, deselectTo: someOtherValue)) { ... }