KVO不适用于集体财产
我试图了解iOS中的关键价值观察,但我认为我没有做正确的事情。 作为一个想法,我试图将观察者添加到视图控制器的属性(与IBOutlet连接的视图)。 这个视图(tableIndicator)是动画的,所以我想看看当视图的框架发生变化时是否可以让观察者作出反应。
所以我在视图控制器的viewDidLoad中做了以下操作:
[tableInidicator addObserver:self forKeyPath:@"frame" options:0 context:nil];
tableIndicator
是我的视图/类属性,我添加视图控制器(自我)作为观察者,0为默认选项和帧作为观察的关键值。
然后,我等着看这个函数是否随着框架的改变而被触发:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
NSLog(@"value changed");
}
...但没有任何反应。
我不一定在寻找修复这个代码的方法,因为除了我理解它之外,它没有任何用处,如果有人能指出我做错了什么,我会非常感激。 一些很好的例子/教程也会很棒。
我发现的那些(http://iphonedevelopment.blogspot.ro/2009/02/kvo-and-iphone-sdk.html/ http://nachbaur.com/blog/back-to-basics-using-kvo)确实不包括这种情况。 他们只是观察者应用到一个类来观察它的一个属性,而不是在一个类内的(自定义)对象的属性,我认为这对我来说更有用。
先谢谢你
对于那些会错过我对接受的答案的评论:
改变视图的中心显然不会触发frame属性的观察者。 你必须改变框架本身。
检查你的IBOutlet是否连接正确,可能是tableIndicator ivar指向零。 考虑下面这个简单的代码,它的工作原理。 它只是创建一个窗口,在其上添加一个红色正方形,然后使用KVO注册要通知更改帧的对象。 最后它会实例化一个按钮:每次点击它时,帧的大小都会减小,并且正确触发通知(您将在调试控制台中看到该消息)。 所以你必须检查你的代码。
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize v = _v;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
self.v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
_v.backgroundColor=[UIColor redColor];
[self.window addSubview:_v];
UIButton *b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
b.frame=CGRectMake(0, 300, 40, 10);
[b setTitle:@"A" forState:UIControlStateNormal];
[b addTarget:self action:@selector(changeFrame) forControlEvents:UIControlEventTouchUpInside];
[_window addSubview:b];
[_v addObserver:self forKeyPath:@"frame" options:0 context:NULL];
return YES;
}
-(void)changeFrame {
CGRect _f = self.v.frame;
_f = CGRectInset(_f, 20, 20);
_v.frame=_f;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSLog(@"Observing...");
}
有一些不完全清楚你的代码。 tableIndicator
是从UIView
派生的自定义类吗? observeValueForKeyPath
方法应该在该类中定义,然后调用它。 但我不确定这是最好的方法。
一般来说,更健全的方法是将您的控制器(而不是您的视图)定义为观察者。 在这种情况下,您可以:
[self addObserver:self forKeyPath:@"view.frame" options:0 context:nil];
从控制器内部某处; observeValueForKeyPath
也将被定义为控制器中的方法。
上一篇: KVO not working for class property
下一篇: Observing Changes to a mutable array using KVO vs. NSNotificationCenter