#import "ViewController.h" @interface ViewController (){ UIImageView *iv; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; iv.image = [UIImage imageNamed:@"haha"]; [self.view addSubview:iv]; [iv addObserver:self forKeyPath:@"center" options:NSKeyValueObservingOptionNew context:nil]; UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 0, 100, 100)]; [myButton setTitle:@"ahahah" forState:UIControlStateNormal]; myButton.layer.borderColor = [[UIColor redColor]CGColor]; myButton.layer.borderWidth = 10; [myButton addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:myButton]; } -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqualToString:@"center"]) { NSLog(@"changed"); } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)click:(id)sender { [UIView animateWithDuration:0.5 animations:^{ iv.frame = CGRectMake(0, 300, 100, 100); } completion:^(BOOL finished){ }]; } @end
结果没有监听到。
但是假如不用UIView的animation ,直接设置点击button之后imageview的frame变化,则可以监听到。这是为什么?怎么解决?谢谢啦先
解决方案:20分
在看了几篇讨论和文章后
1. http://stackoverflow.com/questions/1555690/key-value-observing-during-uiview-animations
2. http://stackoverflow.com/questions/1557739/observing-animated-property-changes-in-a-calayer
3.https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/AnimatableProperties/AnimatableProperties.html#//apple_ref/doc/uid/TP40004514-CH11-SW1
通过timer去选择性的获取属性变化是可靠的办法
动画可以做的属性见3,没有center, kvo观察它没有意义
通过实验实现动画layer的delegate
观察postion靠谱,本人本人实验了一个小程序,仅供参考,希望能对你有帮助~
1. http://stackoverflow.com/questions/1555690/key-value-observing-during-uiview-animations
2. http://stackoverflow.com/questions/1557739/observing-animated-property-changes-in-a-calayer
3.https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/AnimatableProperties/AnimatableProperties.html#//apple_ref/doc/uid/TP40004514-CH11-SW1
通过timer去选择性的获取属性变化是可靠的办法
动画可以做的属性见3,没有center, kvo观察它没有意义
通过实验实现动画layer的delegate
观察postion靠谱,本人本人实验了一个小程序,仅供参考,希望能对你有帮助~
// // ViewController.m // ObsverveAnimationProperty // // Created by xiaomanwang on 14-3-7. // Copyright (c) 2014年 xiaomanwang. All rights reserved. // #import "ViewController.h" static const int duration = 2; @interface ViewController () @property(nonatomic, strong)UIView*viewForAnimated; @property(nonatomic, strong)NSTimer *timer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; _viewForAnimated = [UIView new]; _viewForAnimated.backgroundColor = [UIColor redColor]; _viewForAnimated.frame = CGRectMake(20, 20, 100,100); [self.view addSubview:_viewForAnimated]; _viewForAnimated.layer.delegate = self; UIButton*btn = [UIButton buttonWithType:UIButtonTypeCustom]; [btn setTitle:@"do" forState:UIControlStateNormal]; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [self.view addSubview:btn]; btn.frame = CGRectMake(200, 100, 40, 30); [btn addTarget:self action:@selector(doAnimation) forControlEvents:UIControlEventTouchUpInside]; // [self addObserver:self forKeyPath:@"viewForAnimated.frame" options:NSKeyValueObservingOptionNew context:NULL]; [self addObserver:self forKeyPath:@"viewForAnimated.layer.presentationLayer.position" options:NSKeyValueObservingOptionNew context:NULL]; [self addObserver:self forKeyPath:@"viewForAnimated.layer.presentationLayer.bounds" options:NSKeyValueObservingOptionNew context:NULL]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { //这里观察的presentationlayer没有东西,观察不到,动画的时候的presentationlayer是临时创建的 NSLog(@"change:%@",change); } - (void)doAnimation { self.timer = [NSTimer timerWithTimeInterval:0.01 target:self selector:@selector(getPos) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; CGRect frame = _viewForAnimated.frame; if(_viewForAnimated.frame.origin.y >= 250.0) { frame.origin.y = 20; } else { frame.origin.y = 250; } [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ _viewForAnimated.frame = frame; } completion:^(BOOL finished) { [self performSelector:@selector(stopTimer) withObject:nil afterDelay:duration]; }]; } - (void)stopTimer { if(self.timer) { [self.timer invalidate]; self.timer = nil; } } - (void)getPos { NSLog(@"current pos%@",NSStringFromCGPoint([[_viewForAnimated.layer presentationLayer] position])); } - (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event { NSLog(@"view.layer:%@",_viewForAnimated.layer); NSLog(@"view.layer.presentationLayer:%@",_viewForAnimated.layer.presentationLayer); //这里观察到的event是position NSLog(@"layer:%@:event:%@",layer, event); return nil; } @end