swift - 带 KVO 的简单 MVVM

标签 swift mvvm key-value-observing

我正在尝试使用 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 gets 和 sets 但从未成功

最佳答案

更新

根据 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()

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

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

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

关于swift - 带 KVO 的简单 MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44803375/

相关文章:

ios - 如何更改 UICollectionViewCell 中 UILabel 的值?

MVVM Windows Phone 8 - 向 map 添加图钉集合

silverlight - 动态子用户控件MVVM

c# - ShowDialog 中的 Catel async wait 命令 - 死锁

ios - 为什么在 dealloc 前没有移除 KVO observer 会导致 app crash?

ios - 如何转换此代码以检测相机焦点?

objective-c - 为什么要使用 ivar?

ios - NSFetchRequest 上的 Swift2.0 CoreData 问题

ios - Catalyst 的 ML 构建错误(Xcode 12 GM)

swift - 如何将GB-2312编码改为UTF-8