美文网首页
iOS 动画过程中获取实时变化的属性值

iOS 动画过程中获取实时变化的属性值

作者: 奋进的小时光_Joe | 来源:发表于2018-11-02 19:31 被阅读50次

该本仅为笔者自己的理解,如果有不正确的地方,请不吝指教。

当你在实现某个动画效果是,如果想要监听到当前 view 或者 layer 在动画过程中属性的时,可以通过CALayer 的presentationLayer方法来进行获取。

CALayer 中有一个很有意思的方法:

- (nullable instancetype)presentationLayer;

CALayer中包含了一个presentationLayer表示层和modelLayer模型层

如果你对 layer 添加一个animation动画,当动画开始以后,layer的属性其实并没有发行变化,变化的只是 layer 中表示presentationLayer的属性,所有要获取在动画过程中 layer 的属性,可以通过下面的方式获取

@interface ViewController ()<CAAnimationDelegate>{
    //CADisplayLink本质就是一个和屏幕内容更新同频率的定时器
    CADisplayLink *displayLink;
}
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (nonatomic, strong) CALayer *layer;
@end

@implementation ViewController

- (CADisplayLink *)getDisplayLink{

    if (!displayLink) {
        //初始化 displayLink
        displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLink)];
        //将 displayLink 添加到 RunLoop 中
        [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    }

    return displayLink;
}

- (void)removeDisplayLink{
    
    [displayLink invalidate];
    displayLink = nil;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onRedView)];
    [self.redView addGestureRecognizer:tap];
}

- (void)onRedView{
    
    NSLog(@"-----red view 被点击了");
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //给 redView 添加一个在y轴移动的动画
    CABasicAnimation *anim = [CABasicAnimation animation];
    anim.keyPath = @"position.y";
    anim.toValue = @400;
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    anim.delegate = self;
    [_redView.layer addAnimation:anim forKey:nil];
}

#pragma mark - CAAnimationDelegate

- (void)displayLink{

    NSLog(@"\nprsention.frame - %@\nmodel.frame - %@\nlayer.frame - %@",NSStringFromCGRect(_redView.layer.presentationLayer.frame), NSStringFromCGRect(_redView.layer.modelLayer.frame), NSStringFromCGRect(_redView.layer.frame));
}
//动画开始
- (void)animationDidStart:(CAAnimation *)anim{
    NSLog(@"start-%@",NSStringFromCGRect(_redView.frame));
    [self getDisplayLink];
}

//动画结束
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    //    NSLog(@"stop-%@",NSStringFromCGRect(_redView.frame));
    NSLog(@"stop-%@",NSStringFromCGRect(_redView.layer.presentationLayer.frame));
    [self removeDisplayLink];
}

输出打印结果:

2018-11-02 19:13:22.783428+0800 基础动画[11216:1254495] start-{{0, 20}, {100, 100}}
2018-11-02 19:13:22.784029+0800 基础动画[11216:1254495] 
prsention.frame - {{0, 20.95416596159339}, {100, 100}}
model.frame - {{0, 20}, {100, 100}}
layer.frame - {{0, 20}, {100, 100}}
2018-11-02 19:13:22.787055+0800 基础动画[11216:1254495] -----red view 被点击了
2018-11-02 19:13:22.800747+0800 基础动画[11216:1254495] 
prsention.frame - {{0, 43.088731914758682}, {100, 100}}
model.frame - {{0, 20}, {100, 100}}
layer.frame - {{0, 20}, {100, 100}}
……
2018-11-02 19:13:23.017459+0800 基础动画[11216:1254495] 
prsention.frame - {{0, 329.13446128368378}, {100, 100}}
model.frame - {{0, 20}, {100, 100}}
layer.frame - {{0, 20}, {100, 100}}
2018-11-02 19:13:23.033881+0800 基础动画[11216:1254495] 
prsention.frame - {{0, 349.99868214130402}, {100, 100}}
model.frame - {{0, 20}, {100, 100}}
layer.frame - {{0, 20}, {100, 100}}
2018-11-02 19:13:23.034101+0800 基础动画[11216:1254495] stop-{{0, 349.99868214130402}, {100, 100}}

从打印结果可以看出,layer的位置其实是一直没有发生变化的,View 的位置当然也没有,在动画结束后点击移动过的红色 view 的位置其实并不会响应在 view 上添加的 tag 方法,view 的位置其实还是在之前的位置,移动的位置只是 layer 的表现层的 frame。

复杂的动画效果都是通过多种基本的动画组合行程的,比如说通过获取两个不同动画时间的 view 的位移动画,就可以实时的获取到他们之间的一组差值,利用这个差值来再来做一些曲线的变化之类的动画效果就很方便啦。

如果感觉有帮助的话,请点一个喜欢!

相关文章

  • iOS 动画过程中获取实时变化的属性值

    该本仅为笔者自己的理解,如果有不正确的地方,请不吝指教。 当你在实现某个动画效果是,如果想要监听到当前 view ...

  • 小白学qml 5

    动画( Animations) 动画被⽤于属性的改变。 ⼀个动画定义了属性值改变的曲线, 将⼀个属性值变化从⼀个值...

  • Android属性动画工作原理

    什么是属性动画 更改一个对象的属性值时,值的变化呈现动画效果。如一个Drawable的alpha值变化,或者一个D...

  • 属性动画

    定义 通过不断控制 值 的变化,再不断 手动 赋给对象的属性,从而实现动画效果 使用 已有属性动画 组合属性动画 ...

  • 第一天笔记

    get:获取拓展属性的值,在获取属性值的时候, set:监听扩展属性。当扩展属性发生变化的时候,会自动调用之后,会...

  • 3D效果

    transition从一个属性值变化到另外一个属性值的一个动画效果 animation产生更加复杂的动画 tran...

  • JS动画效果

    JS速度动画 JS透明度动画 JS缓冲动画 JS多物体动画 JS透明度多物体动画 获取样式屬性值 任意属性值 任意...

  • ValueAnimator原理

    概述我们知道,补间动画是设置View相关属性值的起止点,然后系统会值变化中自动给View的属性赋值,但是补间动画只...

  • iOS中的传值方式

    在日常开发过程中,我们经常会遇到值传递。这里,介绍几种iOS开发中常见的传值方式。 1.属性传值 属性传值是iOS...

  • Android 动画

    动画类型 视图动画(补间动画、逐帧动画)属性动画 补间动画 逐帧动画 属性动画 对比 插值器:确定属性值从初始值过...

网友评论

      本文标题:iOS 动画过程中获取实时变化的属性值

      本文链接:https://www.haomeiwen.com/subject/jtacxqtx.html