I have looked around all over for an answer to this and I have tried to implement it, but nothing is working. Basically, I need to be able to observe changes in a VC view's subviews array. If an existing view is removed from that array, I want to be notified about it and run some code.
Is it possible?
EDIT - More information
I am trying to make a fix for a strange edge case bug where rapidly tapping on the UISearchBar of a UISearchDisplayController (very custom) causes the sdController (or rather the managed searchBar in navBar effect) to disappear from the view, but the sdController is STILL ACTIVE. Which means the navBar stays at the -y origin, and the tableView below isn't scrollable.
My original thought was to get to a state where the sdController was active, but the UISearchDisplayControllerContainerView wasn't in the view hierarchy. I tried testing this in the VC's viewDidLayoutSubviews, but alas, when you tap on a search bar and initiate the sdController animation, the sdController is active, and the UISearchDisplayControllerContainerView isn't in the view hierarchy :(.
You can observe property sublayers
of CALayer, which is KVO compliant, instead of UIView subviews
.
As with most properties in Apple's frameworks subviews
is not KVO compliant.
If you control either the subview or the superview you can observe changes to the view hierarchy by subclassing and overriding:
In the superview you have to override...
- (void)willRemoveSubview:(UIView *)subview
... or, if you control the subview, you would override...
- (void)willMoveToSuperview
Both methods are called before the view is removed.
Swift 3.x
use custom view iike
class ObervableView: UIView {
weak var delegate:ObservableViewDelegate?
override func didAddSubview(_ subview: UIView) {
super.didAddSubview(subview)
delegate?.observableView(self, didAddSubview: subview)
}
override func willRemoveSubview(_ subview: UIView) {
super.willRemoveSubview(subview)
delegate?.observableview(self, willRemoveSubview: subview)
}
}
protocol ObservableViewDelegate: class {
func observableView(_ view:UIView, didAddSubview:UIView)
func observableview(_ view:UIView, willRemoveSubview:UIView)
}
//Use
class ProfileViewController1: UIViewController, ObservableViewDelegate {
@IBOutlet var headerview:ObervableView! //set custom class in storyboard or xib and make outlet connection
override func viewDidLoad() {
super.viewDidLoad()
headerview.delegate = self
}
//Delegate methods
func observableView(_ view: UIView, didAddSubview: UIView) {
//do somthing
}
func observableview(_ view: UIView, willRemoveSubview: UIView) {
//do somthing
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With