UIView animation 里面的center值变化了,但是KVO监听不到?

iOS 码拜 4年前 (2015-11-28) 478次浏览
#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靠谱,本人本人实验了一个小程序,仅供参考,希望能对你有帮助~

//
//  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

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明UIView animation 里面的center值变化了,但是KVO监听不到?
喜欢 (0)
[1034331897@qq.com]
分享 (0)