Как избежать бесконечной l oop на наблюдателе быстрых свойств - PullRequest
0 голосов
/ 02 мая 2020

Я пытаюсь реализовать логику c, которая напоминает функциональность слоя «Группа» в некоторых популярных дизайнерских приложениях.

Допустим, у меня есть класс в моем домене, который может иметь несколько дочерних элементов и родительских элементов этого типа. Я хочу, чтобы при обновлении кадра родителя дети пропорционально корректировали свой кадр. Точно так же, когда кадр ребенка изменяется, я бы хотел, чтобы родительский кадр обновлялся, оборачивая его дочерние элементы соответствующим образом.


class Layer {
    var parent: Layer?
    var children: [Layer]

    var frame: CGRect {
        didSet {
            if parent != nil {
                // Tell parent to update its frame
            }

            children.forEach { (child) in
                // tell the child to update it's frame
            }
        }
    }
}

Когда родительский кадр обновляется, он говорит своим детям обновить свои кадры, затем дети возвращаются к родителю с просьбой обновить его кадр. И мы попадаем в бесконечное l oop.

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

Спасибо.

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

Правильный способ обновления графики компонентов - это вызов метода layoutIfNeeded, поэтому вам нужно выполнить

self.layoutIfNeeded();

или

parent.layoutIfneeded();
0 голосов
/ 02 мая 2020

Вы не сможете сделать это со свойством. Вам нужен метод с параметром, указывающим, какой родительский / дочерний слой не нужно обновлять. Поэтому, когда родитель обновляет кадры своих детей, он передает ссылку на себя, чтобы дети не обновляли родительский кадр. И когда дочерний элемент обновляет фрейм своего родителя, он передает ссылку на себя, поэтому родительский элемент не обновляет этот дочерний элемент.

class Layer {
    var parent: Layer?
    var children: [Layer]

    private(set) var frame: CGRect

    func update(frame: CGRect) {
        update(frame: frame, sender: nil)
    }

    private func update(frame: CGRect, sender: Layer? = nil) {
        self.frame = frame

        if sender !== parent {
            parent?.update(frame: SOME_FRAME, sender: self)
        }

        children.forEach { child in
            if child !== sender {
                child.update(frame: SOME_FRAME, sender: self)
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...