objective-cioscocoa-touchuiviewsetneedsdisplay

setNeedsLayout in UIView subviews


I have a UIViewController and in willRotateToInterfaceOrientation, i am calling [self view] setNeedsLayout];

This view call's it's subview's (a UIScrollView) layoutSubviews method, but the UIScrollView doesn't call layoutSubviews for it's subviews. Is this how it's suppose to be? I thought if you call setNeedsLayout on a view, it will call layoutSubviews on each and every subivew and their subviews and on...

Do I have to manually, override layoutsubview in UIScrollView and call setNeedsDisplay for each of the subviews?

Thanks.


Solution

  • I observed the same thing in my app some time ago and it seems that setNeedsLayout only affects the view's subviews and does not traverse down. If you use custom views you can easily subclass the views and iterate over the subviews in setNeedsLayout and perform an explicit setNeedsLayout on them.

    If you want it to be the default behavior you could override the method in a category, but I really would not do this since it affects all views and may introduce performance and other unexpected issues.

    You could do something like this

    @interface UIView (Layout)
      
    - (void)setNeedsLayoutRecursively;
    
    @end
    
    @implementation UIView (Layout)
    
    - (void)setNeedsLayoutRecursively {
      for (UIView *view in self.subviews) {
        [view setNeedsLayoutRecursively];
      }
      [self setNeedsLayout];
    }
    
    @end
    

    typed in browser, not tested

    However, be aware that this is not good practice! You should only update what needs updating. This could result in a severe performance hit. Use with caution!