Swift KVO绑定未更新

时间:2019-01-06 09:32:50

标签: swift macos cocoa datepicker key-value-observing

在我的macOS应用程序中,我想将文本与可视NSDatePicker结合在一起。因此,我制作了一个自定义的NSDatePicker,单击该按钮时会显示一个弹出窗口。

Textual and Visual NSDatePicker

使用绑定检查器将文本选择器链接到变量: binding inspector of textual picker

我的问题是,当在弹出窗口中选择某些内容时会以可视方式更新文本选择器时,绑定值(prop_dateTime)不会更新。

我尝试过的一些方法:

class TextualAndVisualDatePickerElement: NSDatePicker {
    [...]
    func showPopover(sender: NSDatePicker) {
        //using Bond
        self.reactive.objectValue.bidirectionalBind(to: visualDatePicker.reactive.objectValue)

        //using KVO
        visualDatePicker.bind(.value, to: self, withKeyPath: "dateValue", options: [:])

        //using setValue
        _ = self.reactive.objectValue.observeNext(with: {self.setValue($0, forKey: "dateValue")})
        _ = visualDatePicker.reactive.objectValue.observeNext(with: {sender.setValue($0, forKey: "dateValue")})

        //using willChange
        _ = self.reactive.objectValue.observeNext(with: {visualDatePicker.willChangeValue(forKey: "dateValue"); visualDatePicker.dateValue = $0 as! Date; visualDatePicker.didChangeValue(forKey: "dateValue")})
        _ = visualDatePicker.reactive.objectValue.observeNext(with: {self.willChangeValue(forKey: "dateValue"); self.dateValue = $0 as! Date; self.didChangeValue(forKey: "dateValue")})

    }
    [...]
    //using keyPaths
    override public class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
        if key == "dateValue" {
            return Set(["visualDatePicker.dateValue"])
        }
        if key == "visualDatePicker.dateValue" {
            return Set(["dateValue"])
        }
        return Set([])
    }
}

class ViewController: NSViewController {
    @objc dynamic var objectControllerContent : ObjectControllerContent = ObjectControllerContent()

    @IBOutlet weak var label: NSTextField!
    @IBAction func btnClicked(_ sender: Any) {
        label.stringValue = "prop_dateTime is \(objectControllerContent.prop_dateTime)"
    }
}

class ObjectControllerContent : NSObject {
    @objc dynamic var prop_dateTime : Date?
}

结果: Result

github项目:https://github.com/Florrr/VisualNSDatePicker

1 个答案:

答案 0 :(得分:1)

设置dateValue或任何objectValue的{​​{1}}或NSDatePicker不会触发绑定。绑定是在NSControl中触发的。

解决方案:

调用sendAction(_:to:),操作和/或目标可以是sendAction(_:to:)

nil

或模仿绑定

datePicker.dateValue = date
datePicker.sendAction(datePicker.action, to: datePicker.target)