Каковы отношения между setNeedsLayout UIVIEW, layoutIfNeeded и layoutSubviews?

Может любой давать категорическое объяснение на отношениях между UIView's setNeedsLayout, layoutIfNeeded и layoutSubviews методы? И реализация в качестве примера, где все три использовались бы.Спасибо.

То, что получает меня перепутанный, является этим, если я отправляю свое пользовательское представление a setNeedsLayout передайте очень следующую вещь, которую это вызывает после того, как этот метод layoutSubviews, пропуск прямо layoutIfNeeded. Из документов я ожидал бы, что поток будет setNeedsLayout > причины layoutIfNeeded быть названным> причины layoutSubviews быть названным.

105
задан Syed Ali Salman 10 July 2015 в 05:19
поделиться

1 ответ

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

setNeedsLayout прост: он просто устанавливает флаг где-нибудь в UIView, который отмечает его как требующий макета. Это заставит layoutSubviews вызываться в представлении до того, как произойдет следующая перерисовка. Обратите внимание, что во многих случаях вам не нужно вызывать это явно из-за свойства autoresizesSubviews . Если это установлено (что установлено по умолчанию), то любое изменение фрейма представления приведет к тому, что представление будет размещать свои подвиды.

layoutSubviews - это метод, с помощью которого вы делаете все самое интересное. Если хотите, это эквивалент drawRect для макета. Тривиальный пример:

-(void)layoutSubviews {
    // Child's frame is always equal to our bounds inset by 8px
    self.subview1.frame = CGRectInset(self.bounds, 8.0, 8.0);
    // It seems likely that this is incorrect:
    // [self.subview1 layoutSubviews];
    // ... and this is correct:
    [self.subview1 setNeedsLayout];
    // but I don't claim to know definitively.
}

AFAIK layoutIfNeeded обычно не предназначен для переопределения в вашем подклассе. Это метод, который вы должны вызывать, когда хотите, чтобы представление было размещено прямо сейчас . Реализация Apple может выглядеть примерно так:

-(void)layoutIfNeeded {
    if (self._needsLayout) {
        UIView *sv = self.superview;
        if (sv._needsLayout) {
            [sv layoutIfNeeded];
        } else {
            [self layoutSubviews];
        }
    }
}

Вы должны вызвать layoutIfNeeded в представлении, чтобы заставить его (и, при необходимости, его супервизоры) быть размещенными немедленно.

103
ответ дан 24 November 2019 в 04:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: