有没有办法在 SwiftUI Picker 选择更改时调用函数?
Is there a way to call a function when a SwiftUI Picker selection changes?
我想在 selectedOption 的值改变时调用一个函数。有没有办法在 SwiftUI 中执行此操作类似于编辑 TextField?
具体来说,我想在用户更改selectedOption时保存选择的选项。
这是我的选择器:
struct BuilderPicker: View {
let name: String
let options: Array<String>
@State var selectedOption = 0
var body: some View {
HStack {
Text(name)
.font(.body)
.padding(.leading, 10)
Picker(selection: $selectedOption, label: Text(name)) {
ForEach(0 ..< options.count) {
Text(self.options[[=10=]]).tag([=10=])
}
}.pickerStyle(SegmentedPickerStyle())
.padding(.trailing, 25)
}.onTapGesture {
self.selectedOption = self.selectedOption == 0 ? 1 : 0
}
.padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
.border(Color.secondary, width: 3)
.padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
.font(.body)
}
}
我对 SwiftUI 还是个新手,希望得到一些帮助。谢谢!
如果@State 值将在视图中使用,则不需要额外的变量name
struct BuilderPicker: View {
// let name: String = ""
let options: Array<String> = ["1", "2","3","4","5"]
@State var selectedOption = 0
var body: some View {
HStack {
Text(options[selectedOption])
.font(.body)
.padding(.leading, 10)
Picker(selection: $selectedOption, label: Text(options[selectedOption])) {
ForEach(0 ..< options.count) {
Text(self.options[[=10=]]).tag([=10=])
}
}.pickerStyle(SegmentedPickerStyle())
.padding(.trailing, 25)}
// }.onTapGesture {
// self.selectedOption = self.selectedOption == 0 ? 1 : 0
// }
.padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
.border(Color.secondary, width: 3)
.padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
.font(.body)
}
}
如果您需要对@State 进行单独操作,最简单的方法是在视图中添加一行:onReceive()。
HStack {
Text("")
.font(.body)
.padding(.leading, 10)
Picker(selection: $selectedOption, label: Text("")) {
ForEach(0 ..< options.count) {
Text(self.options[[=11=]]).tag([=11=])
}
}.pickerStyle(SegmentedPickerStyle())
.padding(.trailing, 25)}
// }.onTapGesture {
// self.selectedOption = self.selectedOption == 0 ? 1 : 0
// }
.padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
.border(Color.secondary, width: 3)
.padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
.font(.body)
.onReceive([self.selectedOption].publisher.first()) { (value) in
print(value)
}
如果您在回调中更新 ObservedObject
,之前的解决方案将陷入无限循环,因为在呈现视图时也会调用 .onReceive
。
→ 更好的方法是在 Binding 本身上使用 .onChange
方法:
Picker(selection: $selectedOption.onChange(doSomething), label: Text("Hello world")) {
// ...
}
为此,您需要为 Binding
编写一个 extension
,例如 。
我想在 selectedOption 的值改变时调用一个函数。有没有办法在 SwiftUI 中执行此操作类似于编辑 TextField?
具体来说,我想在用户更改selectedOption时保存选择的选项。
这是我的选择器:
struct BuilderPicker: View {
let name: String
let options: Array<String>
@State var selectedOption = 0
var body: some View {
HStack {
Text(name)
.font(.body)
.padding(.leading, 10)
Picker(selection: $selectedOption, label: Text(name)) {
ForEach(0 ..< options.count) {
Text(self.options[[=10=]]).tag([=10=])
}
}.pickerStyle(SegmentedPickerStyle())
.padding(.trailing, 25)
}.onTapGesture {
self.selectedOption = self.selectedOption == 0 ? 1 : 0
}
.padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
.border(Color.secondary, width: 3)
.padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
.font(.body)
}
}
我对 SwiftUI 还是个新手,希望得到一些帮助。谢谢!
如果@State 值将在视图中使用,则不需要额外的变量name
struct BuilderPicker: View {
// let name: String = ""
let options: Array<String> = ["1", "2","3","4","5"]
@State var selectedOption = 0
var body: some View {
HStack {
Text(options[selectedOption])
.font(.body)
.padding(.leading, 10)
Picker(selection: $selectedOption, label: Text(options[selectedOption])) {
ForEach(0 ..< options.count) {
Text(self.options[[=10=]]).tag([=10=])
}
}.pickerStyle(SegmentedPickerStyle())
.padding(.trailing, 25)}
// }.onTapGesture {
// self.selectedOption = self.selectedOption == 0 ? 1 : 0
// }
.padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
.border(Color.secondary, width: 3)
.padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
.font(.body)
}
}
如果您需要对@State 进行单独操作,最简单的方法是在视图中添加一行:onReceive()。
HStack {
Text("")
.font(.body)
.padding(.leading, 10)
Picker(selection: $selectedOption, label: Text("")) {
ForEach(0 ..< options.count) {
Text(self.options[[=11=]]).tag([=11=])
}
}.pickerStyle(SegmentedPickerStyle())
.padding(.trailing, 25)}
// }.onTapGesture {
// self.selectedOption = self.selectedOption == 0 ? 1 : 0
// }
.padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
.border(Color.secondary, width: 3)
.padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
.font(.body)
.onReceive([self.selectedOption].publisher.first()) { (value) in
print(value)
}
如果您在回调中更新 ObservedObject
,之前的解决方案将陷入无限循环,因为在呈现视图时也会调用 .onReceive
。
→ 更好的方法是在 Binding 本身上使用 .onChange
方法:
Picker(selection: $selectedOption.onChange(doSomething), label: Text("Hello world")) {
// ...
}
为此,您需要为 Binding
编写一个 extension
,例如