Swift MVC: наличие viewController для наблюдения свойства модели, обновление представления при изменении свойства - PullRequest
1 голос
/ 23 октября 2019

Основным классом моей модели является Концентрация со свойством flipCount

class Concentration {
    @objc var flipCount = 0

В My ViewController у меня есть @IBOutlet для UILabel с именем flipCountLabel

class ViewController: UIViewController {
    lazy var game = Concentration(numberOfPairsOfCards: self.cardButtons.count / 2)
    @IBOutlet weak var flipCountLabel: UILabel!
...

Я хочуобновите текст в flipCountLabel при изменении flipCount. Я пытаюсь сделать это, поместив вызов метода наблюдения UIViewController в методе viewDontLoad моего ViewController. Есть несколько способов наблюдения. Я не знаю, какой из них правильный, и не могу найти пример того, как и к чему заполнять переменные.

Я пытался использовать self.observe как

    self.observe(KeyPath<Concentration,Int>(game, "flipCount"), changeHandler: {
        self.flipCountLabel.text = "Flip Count: \(flipCount)"
    })

Я пытаюсь обновить flipCountLabel.text ViewControllers при каждом обновлении game.flipCount. Я думаю это кво?

1 Ответ

1 голос
/ 23 октября 2019

Метод observe - это то, что нужно, будь то с некоторыми изменениями в вашем коде.

Измените свой класс Concentration на следующий:

class Concentration: NSObject {
    @objc dynamic var flipCount = 0
}

InДля работы KVO в Swift свойства должны быть помечены как @objc и dynamic. Класс должен наследоваться от NSObject для предотвращения ошибок во время выполнения.

Ваш класс ViewController должен выглядеть примерно так:

class ViewController: UIViewController {
    @objc lazy var game = Concentration()
    @IBOutlet weak var flipCountLabel: UILabel!

    private var observation: NSKeyValueObservation?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.observation = self.observe(\.game.flipCount) { _, _ in
            self.flipCountLabel.text = "\(self.game.flipCount)"
        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        self.observation = nil
    }
}

Свойство game необходимо пометить @objc (еще раз для предотвращения ошибок во время выполнения). Кроме того, документация по методу observe гласит

, когда возвращаемое или недействительное возвращенное NSKeyValueObservation перестает наблюдать

. Вот почему вам нужно сохранитьсильная ссылка на значение, возвращаемое методом observe.

Также рассмотрите возможность использования обозначения KeyPath, которое я использовал здесь. Если вы сделаете опечатку, она не будет выполнена при компиляции, а не во время выполнения.

Надеюсь, это поможет вам!

...