【问题标题】:Swift UI DatePicker won't update @ObservedObject valueSwift UI DatePicker 不会更新 @ObservedObject 值
【发布时间】:2020-08-09 19:03:17
【问题描述】:

我正在使用一个类来存储 @Published 变量,但是当我尝试将自定义 DatePicker 上选择的值传递给类中的 @ObservedObject 时,我收到以下错误:

TimePicker(time: self.$time.**timeSelected**)

无法转换“绑定”类型的值(又名 'Binding')到预期的参数类型'TimeModel'

如何使用选择器值更新@ObservedObject?

完整代码:

struct ContentView: View {
    
    @ObservedObject var time = TimeModel()

    var body: some View {

        ZStack{
            VStack{
                TimePicker(time: self.$time.timeSelected)
                
                Text("You chose \(time.timeSelected/60) minutes")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

class TimeModel: ObservableObject{
     @Published var timeSelected: TimeInterval = 1.0
}
    

struct TimePicker: UIViewRepresentable {
    
    @ObservedObject var time = TimeModel()
    
    func makeUIView(context: Context) -> UIDatePicker {
        let datePicker = UIDatePicker()
        datePicker.datePickerMode = .countDownTimer
        datePicker.addTarget(context.coordinator,
                             action: #selector(Coordinator.updateTime),
                             for: .valueChanged)
        return datePicker
    }
    
    func updateUIView(_ datePicker: UIDatePicker, context: Context) {
        datePicker.minuteInterval = 5
        datePicker.countDownDuration = time.timeSelected
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject {
        let parent: TimePicker
        
        init(_ parent: TimePicker) {
            self.parent = parent
        }
        
        @objc func updateTime(datePicker: UIDatePicker) {
            parent.time.timeSelected = datePicker.countDownDuration
        }
    }
}

【问题讨论】:

    标签: swift datepicker swiftui combine observedobject


    【解决方案1】:

    你需要引用同样的TimeModel实例。

    解决方案是将TimeModel 传递给TimePicker

    struct TimePicker: UIViewRepresentable {
        @ObservedObject var time: TimeModel // <- declare only
    
        ...
    }
    
    struct ContentView: View {
        @ObservedObject var time = TimeModel()
    
        var body: some View {
            ZStack {
                VStack {
                    TimePicker(time: time) // <- pass `TimeModel` here
    
                    Text("You chose \(time.timeSelected / 60) minutes")
                }
            }
        }
    }
    

    注意TimeInterval 指定时间以为单位,而不是分钟。

    这一行:

    @Published var timeSelected: TimeInterval = 1.0
    

    实际上将默认时间设置为 1 秒。

    【讨论】:

    • 感谢您的快速修复。 @pawello2222 为什么在 TimePicker 结构下声明而不初始化 TimeModel?
    • @ThomSides 您希望在这两种情况下都引用TimeModel 的同一个实例 - 所以它只需要创建一次然后传递。
    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    相关资源
    最近更新 更多