[英]Dismiss picker in SwiftUI and reset picker selection to initial value
I am making a view in SwiftUI with a picker-popover.我正在使用选择器弹出窗口在 SwiftUI 中进行查看。 When picking a value and dismissing the view everything works fine.
选择价值并忽略视图时,一切正常。
But I need to be able to dismiss the picker WITHOUT setting the newly selected value, and have it go back to the initial value it had when being opened.但是我需要能够在不设置新选择的值的情况下关闭选择器,并将其 go 恢复为打开时的初始值。
You can see the code here:你可以在这里看到代码:
import SwiftUI
struct ContentView: View {
@State var showPicker = false
@State var selectedPickerOption = 0
let pickerOptions = ["Hello", "World", "Yes"]
var body: some View {
ZStack {
VStack {
Text("Selected Option: \(pickerOptions[selectedPickerOption])")
Button(
action: {
showPicker = true
},
label: {
Text("Open Picker")
.padding()
}
)
}
if showPicker {
PickerPopover(
pickerOptions: pickerOptions,
width: 300,
height: 300,
showPicker: $showPicker,
selectedPickerOption: $selectedPickerOption,
initialPickerOption: selectedPickerOption
)
.background(Color.red)
}
}
}
}
struct PickerPopover: View {
var pickerOptions: [String]
var width: CGFloat
var height: CGFloat
@Binding var showPicker: Bool
@Binding var selectedPickerOption: Int
var initialPickerOption: Int // This one doesn't work yet
func selectOption() {
withAnimation {
showPicker.toggle()
}
}
func cancel() {
// ######### THIS LINE HERE ISN'T WORKING ##############
selectedPickerOption = initialPickerOption
withAnimation {
showPicker.toggle()
}
}
var body: some View {
VStack {
Picker(
selection: $selectedPickerOption,
label: Text("")
) {
ForEach(0 ..< pickerOptions.count) {
Text(self.pickerOptions[$0])
}
}
.pickerStyle(WheelPickerStyle())
Button(action: cancel) {
Text("Cancel")
}
Button(action: selectOption) {
Text("Select")
}
}
.transition(.move(edge: .bottom))
}
}
I believe the first line in the cancel()
function should do the trick - if selectedPickerOption
is set to 0 (or 1, etc) that will reset the picker to that index specifically.我相信
cancel()
function 中的第一行应该可以解决问题 - 如果selectedPickerOption
设置为 0(或 1 等),它将专门将选择器重置为该索引。
I have been unable to set it dynamically though.我一直无法动态设置它。 I have tried passing in an additional value (
intialPickerOption
), but resetting selectedPickerOption = initialPickerOption
does seem to set it to the actual currently selected selectedPickerOption
, and the picker behaves as if that was chosen correctly.我尝试传入一个附加值(
intialPickerOption
),但重置selectedPickerOption = initialPickerOption
似乎确实将其设置为当前实际选择的selectedPickerOption
,并且选择器的行为就像选择正确一样。
What am I possibly missing here?我可能在这里错过了什么?
The problem occurs as you are modifying selectedPickerOption
which will cause your ContentView to reload whenever the picker changes.当您修改
selectedPickerOption
时会出现问题,这将导致您的 ContentView 在选择器更改时重新加载。 Hence, you will pass the selected value as initialPickerOption
.因此,您会将所选值作为
initialPickerOption
传递。 selectedPickerOption
will always be the same like your initial value. selectedPickerOption
将始终与您的初始值相同。
Here is a solution with using local State
in your PickerView and then sync the Binding on Select or don't sync it.这是在您的 PickerView 中使用本地
State
的解决方案,然后在 Select 上同步绑定或不同步它。 I comment the code at these parts我在这些部分注释代码
struct PickerPopover: View {
var pickerOptions: [String]
var width: CGFloat
var height: CGFloat
@Binding var showPicker: Bool
@Binding var selectedPickerOption: Int
@State var localState : Int = 0 //<< Here your local State
func selectOption() {
self.selectedPickerOption = localState //<< Sync the binding with the local State
withAnimation {
showPicker.toggle()
}
}
func cancel() {
//<< do nothing here
withAnimation {
showPicker.toggle()
}
}
var body: some View {
VStack {
Picker(
selection: $localState,
label: Text("")
) {
ForEach(0 ..< pickerOptions.count) {
Text(self.pickerOptions[$0])
}
}
.pickerStyle(WheelPickerStyle())
Button(action: cancel) {
Text("Cancel")
}
Button(action: selectOption) {
Text("Select")
}
}
.transition(.move(edge: .bottom))
.onAppear {
self.localState = selectedPickerOption // << set inital value here
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.