简体   繁体   English

SwiftUI - 选择器更改时选择器绑定不更新

[英]SwiftUI - Picker binding not updating when picker changes

I have a picker in my view as a segmented picker.在我看来,我有一个选择器作为分段选择器。 Whenever I change the picker by sliding it, it does not update/print out the update.每当我通过滑动更改选择器时,它不会更新/打印更新。 If I tap on it, it changes/updates.如果我点击它,它会更改/更新。 Want it to update when I slide it from one option to the other one.当我将它从一个选项滑到另一个选项时,希望它更新。 I also tried it with a.tag modifier instead of.id, and neither work:(我也尝试使用 a.tag 修饰符而不是 .id,但都不起作用:(

private let options = ["option1","option2"]

 @State private var urlMode = 0 {
        didSet {
            print("url mode set to \(urlMode)")
            
        }
    }

var url: String {
            if urlMode == 0 {
               return "www.google.com"
            } else {
               return "www.yahoo.com"
            }
        }

Return ZStack {

 Picker("", selection: $urlMode) {
                    ForEach(0..<options.count) { index in
                        Text(options[index])
                            .id(index)
                    }
                }
                .pickerStyle(SegmentedPickerStyle())
                .padding(.bottom, K.ScreenSize.screenWidth / 50)
                .padding(.horizontal)
                .onTapGesture {
                    if urlMode == 0 {
                        urlMode = 1
                    } else {
                        urlMode = 0
                    }
                }
}

It turns out the value was being set, but it wasn't updating/running the "didSet" portion of my @State var...an easy way for me to tell was to add a Text above my Picker like so:事实证明,该值已被设置,但它没有更新/运行我的@State var 的“didSet”部分......对我来说,一个简单的方法是在我的 Picker 上方添加一个 Text,如下所示:

Text("selection: \(options[urlMode])")

As I changed the picker, this value updated...so, for some reason, the didSet isn't printing, but it is indeed functioning properly...当我更改选择器时,这个值更新了......所以,由于某种原因,didSet 没有打印,但它确实运行正常......

If you are reading this and need another method to run code when this changes, either use jnpdx's answer above, or use a.onChange modifier to your Picker (make sure use it as-is and not as a binding/with a $):如果您正在阅读本文并且需要在此更改时运行代码的另一种方法,请使用上面的 jnpdx 答案,或对您的 Picker 使用 a.onChange 修饰符(确保按原样使用它,而不是作为绑定/使用 $):

.onChange(of: urlMode) { value in
                    //code to run
                }

There are a number of ways to achieve the link you're looking for.有多种方法可以实现您正在寻找的链接。 I recommend an ObservableObject with a @Published property, which you can observe with onReceive to do your print statement.我推荐一个带有@Published属性的ObservableObject ,您可以使用onReceive观察它来执行您的打印语句。

The tag is now working with the ForEach as well:tag现在也可以与ForEach一起使用:

class ViewModel : ObservableObject {
    let options = ["option1","option2"]
    @Published var urlMode = 0
}

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
    
    var url: String {
        if viewModel.urlMode == 0 {
            return "www.google.com"
        } else {
            return "www.yahoo.com"
        }
    }
    
    var body: some View {
        ZStack {
            Picker("", selection: $viewModel.urlMode) {
                ForEach(Array(viewModel.options.enumerated()), id: \.1.self) { (index,option) in
                    Text(option).tag(index)
                }
            }
            .pickerStyle(SegmentedPickerStyle())
            .padding(.horizontal)
        }.onReceive(viewModel.$urlMode) { (mode) in
            print("url mode set to \(mode)")
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM