KVO 检查 objective c 中 UIView 中所有子视图的 clipsToBounds 的变化
KVO check for change of clipsToBounds of all subviews in an UIView in objective c
我正在尝试为我的 UIView 中所有子视图的 clipsToBounds 属性 实现一个 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 中写什么来更改 clipsToBounds 属性?任何帮助表示赞赏。
当然添加观察者必须在它工作之前完成。
猜测您在“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 的 class KVO 工作,否则如果 super 的实现依赖于观察它们,这些将被忽略.如果需要,这还应该解释如何观察所有子视图。但是想一想,如果 UIView 的子 class 实现它并且所有子视图(或您喜欢的子视图)也将从这个特殊的子 class 继承,那么可能会有大量子视图触发 observeValueForKeyPath。
当您在观察它的 KVO 内部更改 clipsToBounds 时,您可能会调用一个循环,特别是当您同时观察旧值和新值时。你会改变 属性,属性 触发 kvo,kvo 改变 属性,属性 触发 kvo 等等。
设置[self.navigationController.view setClipsToBounds:YES]
更改属性。但如果在 KVO 内部完成,它将再次触发 KVO,如前所述。
通常你会在 -initWithFrame:
或 -initWithCoder:
中或通过 Interface Builder 设置 clipsToBounds 并且可能只是观察它是否被更改以适应其他代码。
旁注:上下文只需要是唯一的,以将其与其他 KVO 区分开来。它也可以是对真实对象指针的引用。
不要忘记在释放之前必须移除添加的观察者。
我正在尝试为我的 UIView 中所有子视图的 clipsToBounds 属性 实现一个 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 中写什么来更改 clipsToBounds 属性?任何帮助表示赞赏。
当然添加观察者必须在它工作之前完成。 猜测您在“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 的 class KVO 工作,否则如果 super 的实现依赖于观察它们,这些将被忽略.如果需要,这还应该解释如何观察所有子视图。但是想一想,如果 UIView 的子 class 实现它并且所有子视图(或您喜欢的子视图)也将从这个特殊的子 class 继承,那么可能会有大量子视图触发 observeValueForKeyPath。
当您在观察它的 KVO 内部更改 clipsToBounds 时,您可能会调用一个循环,特别是当您同时观察旧值和新值时。你会改变 属性,属性 触发 kvo,kvo 改变 属性,属性 触发 kvo 等等。
设置[self.navigationController.view setClipsToBounds:YES]
更改属性。但如果在 KVO 内部完成,它将再次触发 KVO,如前所述。
通常你会在 -initWithFrame:
或 -initWithCoder:
中或通过 Interface Builder 设置 clipsToBounds 并且可能只是观察它是否被更改以适应其他代码。
旁注:上下文只需要是唯一的,以将其与其他 KVO 区分开来。它也可以是对真实对象指针的引用。
不要忘记在释放之前必须移除添加的观察者。