KVO检查目标c中UIView中所有子视图的clipseToBounds的变化



我正在尝试为UIView中所有子视图的clipseToBounds属性实现一个KVO示例。我不太明白如何更改observeValueForKeyPath方法中的值。我使用的是这个代码:

-(void)ViewDidLoad{
[self.navigationController.view addObserver:self forKeyPath:@"clipsToBounds" options:NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld context:nil];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSLog(@"Triggered...")
}

当我更改UIView中存在的子视图的属性clipToBounds时,就会触发它。对于发生的每个触发器,我都需要将值改回false。我应该在observeValueForKeyPath中写些什么来更改clipseToBounds属性?感谢您的帮助。

当然,添加Observer必须先完成,然后才能工作。猜测你在";ViewDidLoad";永远不会被调用,因为它应该是";viewDidLoad";。除此之外,你的KVO模式可能看起来像。。

static void *kvoHelperClipsToBounds = &kvoHelperClipsToBounds;
-(void)viewDidLoad {
[self.navigationController.view addObserver:self forKeyPath:@"clipsToBounds" options:NSKeyValueObservingOptionNew context:&kvoHelperClipsToBounds];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == kvoHelperClipsToBounds) {
NSLog(@"context compared successful...");
//be careful what you cast to.. i dont check isKindOf here.
UINavigationBar* navbar = (UINavigationBar*)object;
if (navbar.subviews.count > 1) {
__kindof UIView *sub = navbar.subviews[1];
if (sub.clipsToBounds) {
dispatch_async(dispatch_get_main_queue(),^{
sub.clipsToBounds = NO;
[self.navigationItem.titleView layoutIfNeeded];
});
}
}
} 
// or compare against the keyPath
else if ([keyPath isEqualToString:@"clipsToBounds"]) {
NSLog(@"classic Key compare Triggered...");
}
else
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}

[super observeValueForKeyPath...]将未识别的keyPath传递给super,以使super的类KVO工作,否则,如果super的实现依赖于观察它们,则这些keyPath将被忽略。如果需要的话,它还应该解释如何观察所有子视图。但是,想想看,如果UIView的一个子类实现了observeValueForKeyPath,并且所有子视图(或您喜欢的子视图(也将从这个特殊的子类继承,那么可能会有成千上万的子视图触发observeVValueForKeyPath。

当您在KVO中观察clipseToBounds时,您可能会调用一个循环,特别是当您同时观察旧值和新值时。您可以更改属性,属性触发kvo,kvo更改属性,该属性触发kvo-on和on。

设置[self.navigationController.view setClipsToBounds:YES]以更改特性。但如果在KVO内部完成,它将再次触发KVO,如所解释的。通常,您会在-initWithFrame:-initWithCoder:中或通过接口生成器设置clipseToBounds,并可能只是观察它是否被更改以适应其他代码。

旁注:上下文只需要是唯一的,就可以将其与其他KVO区分开来。。它也可以是对真实对象指针的引用。

不要忘记,在解除分配之前,必须删除添加的观察者。

最新更新