'iOS Detect subviews being added to UIViewContoller's view

I have a scrollView to which custom views are being added and removed in response to user interaction. I want to make sure the container view is always big enough to display all the subviews, and would like to detect when a view was added or removed. I tried using KVO:

[self.scrollView addObserver:self forKeyPath:@"subviews" options:NSKeyValueObservingOptionNew context:nil];

But while there was no error, observeValueForKeyPath:... method never gets called when the number of subviews change. What should I use instead?

P.S. I know I could put the calculation of desired contentSize property directly into the methods that add/remove subviews to scrollView, but for architectural reasons, this option is inferior to me and I'd prefer to something like KVO instead. Are there options like this?



Solution 1:[1]

"subviews" is always there when UIView is created, try observing on "subviews.count". Or the better way, use following API from UIView:

- (void)didAddSubview:(UIView *)subview

Please refer to: "Observing View-Related Changes" here.

Solution 2:[2]

You can't KVO subviews but you can KVO sublayers which will also get called if a subview is added

[self.view.layer addObserver:self forKeyPath:@"sublayers" options:NSKeyValueObservingOptionNew context:nil];

Solution 3:[3]

For some reason I kept getting the following error when I tried to use addObserver(forKeyPath:options:context:) in Swift:

An -observeValueForKeyPath:ofObject:change:context: message was received but not handled

So I ended-up using the Swift-specific KVO API:

token = view.layer.observe(\.sublayers, options: [.old, .new]) { _, change in
    print("Observed: \(change)")
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 bcattle
Solution 2
Solution 3 LuisCien