Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IOS, UIView, Detect Hidden State Change in Subview

Is there anyway to detect a hidden state change (or other change) in a sub view in a UIView (not UIViewController). Would like to detect this async somehow.

There are reasons for my madness.

like image 319
ort11 Avatar asked Jun 10 '13 22:06

ort11


2 Answers

You can use KVO (key value observing) to detect a change to the value of the property hidden.

Add your observer (self in this example) in the following way:

UIView* viewToObserve = [self getViewToObserve];  // implement getViewToObserve
[viewToObserve addObserver:self forKeyPath:@"hidden" options:0 context:NULL];

Now add the following method to your observer class:

- (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
  UIView* viewToObserve = [self getViewToObserve];
  if (object == viewToObserve)
  {
    if ([keyPath isEqualToString:@"hidden"])
    {
      // react to state change
    }
  }
}

The observer method will be invoked whenever the hiddenproperty changes its value. If I am not mistaken, the method will be invoked synchronously in the context of the thread that makes the change to the property. If you need asynchronous notification you can add that yourself, for instance by using one of the NSObject methods performSelector:withObject:afterDelay: or performSelector:onThread:withObject:waitUntilDone:.

BTW: You don't need the checks in the observer method, obviously, if you only observe a single object and/or property. I left the checks in for illustration purposes. I also recommend reading Apple's documentation on KVO and KVC (key value coding) to understand what's going on here.

The runtime happily continues notifying your observer even if the observer is deallocated - resulting in an application crash! So don't forget to remove the observer before it is de-allocated, at the latest this should happen in the observer's dealloc:

- (void) dealloc
{
    UIView* viewToObserve = [self getViewToObserve];
    [viewToObserve removeObserver:self forKeyPath:@"hidden"];
    [super dealloc];
}
like image 121
herzbube Avatar answered Nov 16 '22 10:11

herzbube


You can override the property in the UIView subclass and do anything in didSet

class MyView: UIView {
   override var isHidden: Bool {
        didSet {
            //do something
        }
    }
}
like image 40
K_Mohit Avatar answered Nov 16 '22 10:11

K_Mohit