setNeedsLayout в подвидах UIView

#objective-c #ios #cocoa-touch #uiview #setneedsdisplay

#objective-c #iOS #cocoa-touch #uiview #setneedsdisplay

Вопрос:

У меня есть UIViewController и в willRotateToInterfaceOrientation , я вызываю [self view] setNeedsLayout];

Этот вызов view — это метод subview (a UIScrollView ) layoutSubviews , но UIScrollView он не вызывает layoutSubviews его subviews. Так ли это должно быть? Я думал, что если вы вызовете setNeedsLayout представление, оно будет вызывать layoutSubviews каждый подраздел и их подразделы и так далее…

Должен ли я вручную переопределять layoutsubview UIScrollView и вызывать setNeedsDisplay для каждого из подвидов?

Спасибо.

Ответ №1:

Некоторое время назад я наблюдал то же самое в своем приложении, и кажется, что setNeedsLayout это влияет только на подвиды представления и не перемещается вниз. Если вы используете пользовательские представления, вы можете легко подклассировать представления и перебирать подвиды в setNeedsLayout и выполнять явное setNeedsLayout для них.

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

Вы могли бы сделать что-то вроде этого

 @interface UIView (Layout)
  
- (void)setNeedsLayoutRecursively;

@end

@implementation UIView (Layout)

- (void)setNeedsLayoutRecursively {
  for (UIView *view in self.subviews) {
    [view setNeedsLayoutRecursively];
  }
  [self setNeedsLayout];
}

@end
  

введено в браузере, не проверено

Однако имейте в виду, что это не очень хорошая практика! Вы должны обновлять только то, что нуждается в обновлении. Это может привести к серьезному снижению производительности. Используйте с осторожностью!

Комментарии:

1. Спасибо.. Я надеялся, что мне не нужно этого делать, хотел избежать этого. На самом деле не хочу просматривать много UIViews, поскольку у меня глубокая иерархия представлений. В любом случае, большое спасибо за вашу помощь.

2. отличный небольшой набор кодов для выбора, который отлично решил мою проблему. Спасибо!

3. Но дочерним представлениям не нужно беспокоиться о состоянии родителя. Только если границы дочернего представления изменились, дочерний элемент необходимо снова выложить. Это может произойти, если layoutSubviews родительского layoutSubviews (или авторазмерные маски) изменяют размер дочернего элемента. В этой ситуации layoutSubviews распространяется вниз по иерархии представлений.

4. @VaddadiKartick да, используйте с осторожностью. Исправлен ответ.