设为首页 加入收藏

TOP

属性动画(显示动)(一)
2017-10-11 13:58:05 】 浏览:5271
Tags:属性 动画 显示

属性动画

CAAnimationDelegate在任何头文件中都找不到,但是可以在CAAnimation头文件或者苹果开发者文档中找到相关函数。在这个例子中,我们用-animationDidStop:finished:方法在动画结束之后来更新图层的backgroundColor

当更新属性的时候,我们需要设置一个新的事务,并且禁用图层行为。否则动画会发生两次,一个是因为显式的CABasicAnimation,另一次是因为隐式动画,具体实现见订单8.3。

清单8.3 动画完成之后修改图层的背景色

 1 @implementation ViewController
 2 
 3 - (void)viewDidLoad
 4 {
 5     [super viewDidLoad];
 6     //create sublayer
 7     self.colorLayer = [CALayer layer];
 8     self.colorLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
 9     self.colorLayer.backgroundColor = [UIColor blueColor].CGColor;
10     //add it to our view
11     [self.layerView.layer addSublayer:self.colorLayer];
12 }
13 
14 - (IBAction)changeColor
15 {
16     //create a new random color
17     CGFloat red = arc4random() / (CGFloat)INT_MAX;
18     CGFloat green = arc4random() / (CGFloat)INT_MAX;
19     CGFloat blue = arc4random() / (CGFloat)INT_MAX;
20     UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
21     //create a basic animation
22     CABasicAnimation *animation = [CABasicAnimation animation];
23     animation.keyPath = @"backgroundColor";
24     animation.toValue = (__bridge id)color.CGColor;
25     animation.delegate = self;
26     //apply animation to layer
27     [self.colorLayer addAnimation:animation forKey:nil];
28 }
29 
30 - (void)animationDidStop:(CABasicAnimation *)anim finished:(BOOL)flag
31 {
32     //set the backgroundColor property to match animation toValue
33     [CATransaction begin];
34     [CATransaction setDisableActions:YES];
35     self.colorLayer.backgroundColor = (__bridge CGColorRef)anim.toValue;
36     [CATransaction commit];
37 }
38 
39 @end
View Code

 

CAAnimation而言,使用委托模式而不是一个完成块会带来一个问题,就是当你有多个动画的时候,无法在在回调方法中区分。在一个视图控制器中创建动画的时候,通常会用控制器本身作为一个委托(如清单8.3所示),但是所有的动画都会调用同一个回调方法,所以你就需要判断到底是那个图层的调用。

考虑一下第三章的闹钟,“图层几何学”,我们通过简单地每秒更新指针的角度来实现一个钟,但如果指针动态地转向新的位置会更加真实。

我们不能通过隐式动画来实现因为这些指针都是UIView的实例,所以图层的隐式动画都被禁用了。我们可以简单地通过UIView的动画方法来实现。但如果想更好地控制动画时间,使用显式动画会更好(更多内容见第十章)。使用CABasicAnimation来做动画可能会更加复杂,因为我们需要在-animationDidStop:finished:中检测指针状态(用于设置结束的位置)。

动画本身会作为一个参数传入委托的方法,也许你会认为可以控制器中把动画存储为一个属性,然后在回调用比较,但实际上并不起作用,因为委托传入的动画参数是原始值的一个深拷贝,从而不是同一个值。

当使用-addAnimation:forKey:把动画添加到图层,这里有一个到目前为止我们都设置为nilkey参数。这里的键是-animationForKey:方法找到对应动画的唯一标识符,而当前动画的所有键都可以用animationKeys获取。如果我们对每个动画都关联一个唯一的键,就可以对每个图层循环所有键,然后调用-animationForKey:来比对结果。尽管这不是一个优雅的实现。

幸运的是,还有一种更加简单的方法。像所有的NSObject子类一样,CAAnimation实现了KVC(键-值-编码)协议,于是你可以用-setValue:forKey:-valueForKey:方法来存取属性。但是CAAnimation有一个不同的性能:它更像一个NSDictionary,可以让你随意设置键值对,即使和你使用的动画类所声明的属性并不匹配。

这意味着你可以对动画用任意类型打标签。在这里,我们给UIView类型的指针添加的动画,所以可以简单地判断动画到底属于哪个视图,然后在委托方法中用这个信息正确地更新钟的指针(清单8.4)。

清单8.4 使用KVC对动画打标签

 1 @interface ViewController ()
 2 
 3 @property (nonatomic, weak) IBOutlet UIImageView *hourHand;
 4 @property (nonatomic, weak) IBOutlet UIImageView *minuteHand;
 5 @property (nonatomic, weak) IBOutlet UIImageView *secondHand;
 6 @property (nonatomic, weak) NSTimer *timer;
 7 
 8 @end
 9 
10 @implementation ViewController
11 
12 - (void)viewDidLoad
13 {
14     [super viewDidLoad];
15     //adjust anchor points
16     self.secondHand.layer.anchorPoint = CGPointMake(0.5f, 0.9f);
17     self.minuteHand.layer.anchorPoint = CGPointMake(0.5f, 0.9f);
18     self.hourHand.layer.anchorPoint = CGPointMake(0.5f, 0.9f);
19     //start timer
20     self
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇iOS9 App Thinning(应用瘦身)功能.. 下一篇iOS9 App Thinning(应用瘦身)功能..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目