【问题标题】:Simple MVVM with KVO带有 KVO 的简单 MVVM
【发布时间】:2017-12-01 20:53:40
【问题描述】:

我正在尝试使用 kvo 创建一个简单的 mvvm 模型

我的目标是当 UITextField 文本更改时,自动更改 UILabel 文本。 但是由于某种原因,observeValue 函数没有被调用

import UIKit
class ViewController: UIViewController, UITextFieldDelegate {

    var viewModel : TestViewModel?
    @IBOutlet weak var LBLABEL: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        viewModel = TestViewModel()

        addObserver(self, forKeyPath: #keyPath(viewModel.infoText), options:  [.old, .new], context: nil)

        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        viewModel?.infoText = textField.text
        return true
    }


    // MARK: - Key-Value Observing
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "info" {
            // Update Time Label
            LBLABEL.text = viewModel?.infoText
        }
    }

}


class TestViewModel : NSObject{
    var model : TestModel

    var infoText:String? {
        didSet{
            model.info = self.infoText

        }
    }

    override init() {
        model = TestModel()
    }
}


class TestModel {
    var info:String?
}

我已经尝试更改观察者的声明,甚至 ViewModel 获取和设置但从未成功

【问题讨论】:

  • 您是否在代码中的某处添加了textField.delegate = self
  • @Ahmad F - 是的。在故事板中。我在shouldChangeCharactersIn 上放了一些断点,代码停在那里。模型和视图模型中字符串的值被正确更改

标签: swift mvvm key-value-observing


【解决方案1】:

更新

根据 Apple 文档,在 Swift 4 中为键路径创建观察者会简单得多。

class MyObserver: NSObject {
    @objc var objectToObserve: MyObjectToObserve
    var observation: NSKeyValueObservation?

    init(object: MyObjectToObserve) {
        objectToObserve = object
        super.init()

        observation = observe(\.objectToObserve.myDate) { object, change in
            print("Observed a change to \(object.objectToObserve).myDate, updated to: \(object.objectToObserve.myDate)")
        }
    }
}

let observed = MyObjectToObserve()
let observer = MyObserver(object: observed)

observed.updateDate()

您需要将dynamic 添加到您要观察的NSObject 子类的属性中。在你的情况下:

@objc dynamic var infoText:String? {
    didSet{
        model.info = self.infoText            
    }
}

顺便说一句,我不知道你为什么想要 textField:shouldChangeCharactersIn 因为它在更新之前获取文本字段值。此外,keyPath == "info" 永远不会是真的。不应该是别的吗。例如,keyPath == "viewModel.infoText"?

【讨论】:

    猜你喜欢
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2015-03-21
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    相关资源
    最近更新 更多