Cocoa

iOS 动画

2021-01-28  本文已影响0人  望穿秋水小作坊

一、动画基本知识

1. iOS动画(或者所有动画)的原理简单来讲有两种,是哪两种?
2. 下面是一张 iOS 动画相关 framework 的架构图,请说出 UIKit/AppKit、Core Animation、Core Graphics 的难度和灵活度?
image.png

从图中可以看到,要实现一个 iOS 动画从上层到底层,你会接触到 UIKit、Core Animation、Core Graphics。他们的使用难度一次递增,相应地灵活程度以及能实现效果的复杂程度也越来越高。

3. CALayer 有很多有用的子类,说几个常用的?
4. UIView 和 CALyer 是什么关系?(重要,至少说 2 点)

二、 UIView 的 Block 动画

1. UIView 的 Block 动画的适用范围
2. 使用 Block 实现普通动画,请问下面的 NSLog(@"Animating");什么时间点被执行?
[UIView animateWithDuration:2.0 delay:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
    self.redView.center = CGPointMake(200, 300);
    NSLog(@"Animating");
} completion:^(BOOL finished) {
    NSLog(@"finished");
}];
3. 使用 Block 实现关键帧动画
[UIView animateKeyframesWithDuration:6.f
                               delay:0.0
                             options:UIViewKeyframeAnimationOptionCalculationModeLinear
                          animations:^{
    [UIView addKeyframeWithRelativeStartTime:0.0   // 相对于6秒所开始的时间(第0秒开始动画)
                            relativeDuration:1/3.0 // 相对于6秒动画的持续时间(动画持续2秒)
                                  animations:^{
        self.view.backgroundColor = [UIColor redColor];
    }];
    
    [UIView addKeyframeWithRelativeStartTime:1/3.0 // 相对于6秒所开始的时间(第2秒开始动画)
                            relativeDuration:1/3.0 // 相对于6秒动画的持续时间(动画持续2秒)
                                  animations:^{
        self.view.backgroundColor = [UIColor yellowColor];
    }];
    [UIView addKeyframeWithRelativeStartTime:2/3.0 // 相对于6秒所开始的时间(第4秒开始动画)
                            relativeDuration:1/3.0 // 相对于6秒动画的持续时间(动画持续2秒)
                                  animations:^{
        self.view.backgroundColor = [UIColor greenColor];
    }];
    
}
                          completion:^(BOOL finished) {
    NSLog(@"finished");
}];
4. 思考下面代码,每一句打印是在什么时间点?
self.destinationPoint = CGPointMake(300, 300);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    NSLog(@"dispatch_after");
    self.destinationPoint = CGPointMake(-200, -200);
});
[UIView animateWithDuration:2.0 delay: 4.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
    self.redView.center = self.destinationPoint;
    NSLog(@"Animating");
} completion:^(BOOL finished) {
    NSLog(@"finished");
}];

三、 Core Animation 动画

1. Core Animation 动画的适用场景?
2. Core Animation 的所有功能都是基于 layer 对吗?
3. Core Animation 实际维护了三个 layer,是哪三个?分别有什么用?
4. Timing Function 是用来干什么的?
5. CABasicAnimation 示例
CABasicAnimation *baseAnimation = [CABasicAnimation animationWithKeyPath:@"position.x"];
baseAnimation.fromValue = @10;
baseAnimation.toValue = @300;
baseAnimation.duration = 1.0;
baseAnimation.fillMode = kCAFillModeForwards; // fillMode 属性为 kCAFillModeForward 以留在最终状态
baseAnimation.removedOnCompletion = NO; // removedOnCompletion 为 NO 以防止它被自动移除
[self.rocketImageView.layer addAnimation:baseAnimation forKey:@"baseAnimation"];
3. CAKeyframeAnimation 路径动画示例
self.rocketImageView.center = self.cycleView.center;

CGRect boundingRect = CGRectMake(-150, -150, 300, 300);

CAKeyframeAnimation *orbit = [CAKeyframeAnimation animation];
orbit.keyPath = @"position";
/// 使用 CGPathCreateWithEllipseInRect(),我们创建一个圆形的 CGPath 作为我们的关键帧动画的 path。
orbit.path = CFAutorelease(CGPathCreateWithEllipseInRect(boundingRect, NULL));
orbit.duration = 4;
/// 连续动画必须要设置为YES,让下一个动画,基于上一个动画
orbit.additive = YES;
orbit.repeatCount = HUGE_VALF;
/// 使用 calculationMode 是控制关键帧动画时间的另一种方法。
/// 我们通过将其设置为 kCAAnimationPaced,让 Core Animation 向被驱动的对象施加一个恒定速度,
/// 不管路径的各个线段有多长。将其设置为 kCAAnimationPaced 将无视所有我们已经设置的 keyTimes。
orbit.calculationMode = kCAAnimationPaced;
/// 设置 rotationMode 属性为 kCAAnimationRotateAuto 确保飞船沿着路径旋转。
/// 作为对比,如果我们将该属性设置为 nil 那动画会是什么样的呢。
orbit.rotationMode = kCAAnimationRotateAuto;
//    orbit.rotationMode = nil;
[self.rocketImageView.layer addAnimation:orbit forKey:@"orbit"];
6. CAAnimationGroup 动画示例
CABasicAnimation *zPositon = [CABasicAnimation animation];
zPositon.keyPath = @"zPosition";
zPositon.fromValue = @-1;
zPositon.toValue = @1;
zPositon.duration = 1.2;

CAKeyframeAnimation *rotation = [CAKeyframeAnimation animation];
rotation.keyPath = @"transform.rotation";
rotation.values = @[@0, @0.14, @0];
rotation.duration = 1.2;
rotation.timingFunctions = @[
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
];

CAKeyframeAnimation *position = [CAKeyframeAnimation animation];
position.keyPath = @"position";
position.values = @[
    [NSValue valueWithCGPoint:CGPointZero],
    [NSValue valueWithCGPoint:CGPointMake(110, -20)],
    [NSValue valueWithCGPoint:CGPointZero]
];
position.timingFunctions = @[
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]
];
position.additive = YES;
position.duration = 1.2;

CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
group.animations = @[zPositon, rotation, position];
group.duration = 1.2;
//    group.beginTime = 0.5;

[self.oneImageView.layer addAnimation:group forKey:@"shuffle"];

self.oneImageView.layer.zPosition = 1;
上一篇 下一篇

猜你喜欢

热点阅读