Search code examples
iphonecocoa-touchuiviewuikitlayoutsubviews

Possible to make superView intercept layoutSubviews: from subviews?


To allow for flexible layouts, I wanted to create a subclass UIView that overrides layoutSubviews: to layout all of its subviews under each other automagically and would continue to do this every time one of its subviews got resized.

However, the only way that I can think of to let the superview know that it should call layoutSubviews: is by overriding that method in each of its subviews, something that I would like to try and avoid (I want people to be able to add arbitrary UIViews to the superview and have this taken care of).

Is there a way for the superview to call layoutSubviews: whenever a subview changes its size, without adding any code to the subview in question?


Solution

  • You could use KVO to observe the frame property of each of your subviews. You would need to add yourself as an observer each time a subview is added and remove the observation when a subview is removed – you can override didAddSubview: and willRemoveSubview: in your superview to do that.

    - (void)didAddSubview:(UIView *)subview {
        [subview addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
    }
    
    - (void)willRemoveSubview:(UIView *)subview {
        [subview removeObserver:self forKeyPath:@"frame"];
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        if ([keyPath isEqualToString:@"frame"]) {
             // Do your layout here...
        }
    }
    
    - (void)dealloc {
        // You might need to remove yourself as an observer here, in case
        // your subviews are still used by others
    }