Core Animation 五 (美化图层,用动作实现自定义动画、为自定义的属性添加动画以及线程)
来源:互联网 发布:淘宝网广场舞扇子 编辑:程序博客网 时间:2024/05/16 15:11
美化图层
CALayer相对于UIView有一个主要优点,即便你工作在2D环境中,CALayer也支持自动边框效果。比如说,CALayer可以自动生成圆角、彩色边线以及阴影。所有这些都可应用动画效果,可以提供非常好的视觉体验。举个例子,你可以在用户点击并释放图层时出发更改位置和阴影的动画效果
CALayer *layer = [CALayer layer];layer.frame = CGRectMake(100,100,100,100);layer.cornerRadius = 10;layer.backgroundColor = [[UIColor redColor] CGColor];layer.borderColor = [[UIColor blueColor] CGColor];layer.borderWidth = 5;layer.shadowOpacity = 0.5;layer.shadowOffset = CGSizeMake(3.0,3.0);[self.view.layer addSublayer:layer];
用动作实现自动动画
隐式动画大多数情况下能达到你的要求,不过有时你还要配置它们。可以通过CATransaction关闭所有隐式动画,不过这只对当前事务(通常就是当前的运行循环)有效。如果要修改隐式动画行为,尤其是想让它针对该图层一直保持这种行为,就需要配置图层的动作。这样,可以在创建图层的时候就配置动画,而不需要每次更改一个属性都应用一个显式动画。
图层动作会相应图层上的各种变化,比如添加或移除图层或者修改某个属性。丽日,假设修改position属性,默认动作是执行动画的0.25秒。在下面的代码中,CirecleLayer是一个在中间依据指定的radius(半径)绘制红色圆圈的图层。
CircleLayer *circleLayer = [CircleLayer new];circleLayer.radius = 20;circleLayer.frame = self.view.bounds;[self.view.layer addSubLayer:circleLayer];...[circleLayer setPosition:CGPointMake(100,100)];//我们来修改它,以使更改位置时动画一直是2秒CircleLayer *circleLayer = [CircleLayer new];circleLayer.radius = 20;circleLayer.frame = self.view.bounds;[self.view.layer addSubLayer:circleLayer];CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];anim.duration = 2;NSMutableDictionary *actions = [NSMutableDictionary dictionaryWithDictionary:[circleLayer actions]];[actions setObject:anim forKey:@"position"];circleLayer.actions = actions;...[circleLayer setPosition:CGPointMake(100,100)];
设置动作为[NSNull null]可以禁用这个属性的隐式动画。字典中不可以保存nil,所以必须使用NSNull类。
有一些特殊的动作用于图层树中添加图层(KCAOnOrderIn)或移除图层(KCAOnOrderOut)时,举个例子,可以创建一组变大同时淡入的动画:
CABasicAnimation *fadeAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];fadeAnim.fromValue = [NSNumber numberWithDouble:0.4];fadeAnim.toValue = [NSNumber numberWithDouble:1.0];CABasicAnimation *growAnim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];growAnim.fromValue = [NSNumber numberWithDouble = 0.8];growAnim.toValue = [NSNumber numberWithDoule:1.0];CAAnimationGroup *groupAnim = [CAAnimationGroup animation];groupAnim.animations = [NSArray arrayWithObjects:fadeAnim,growAnim,nil];[actions setObject:groupAnim forKey:KCAOnOrderIn];
在图层替换时,动作对处理过渡(KCATransition)也非常重要。一般都是与CATransition(一个特殊类型的CAAnimation)一起使用。可以针对contents属性使用CATransition动作来创建特效,比如内容改变时的幻灯片放映效果。默认是启动淡入淡出。
为自定义属性添加动画
Core Animation 隐式地为很多图层属性添加动画,但CALayer子类的自定义属性呢,比如CircleLayer中的radius属性?默认情况下,radius是没有动画的,而contents有(通过CATransition)。因此,更改半径会导致圆形渐渐消失并出现新的图形。这可能不是你想要的结果,你可能希望radius的动画效果像position一样,通过以下几步就可以完成
@implementation CircleLayer@dynamic radius;-(id)init{self = [super init];if(self){[self setNeedsDisplay];}}-(id)initWithLayer:(id)layer{self = [super initWithLayer:layer];[self setRadius:[layer radius]];return self;}-(void)drawInContext:(CGContextRef)ctx{CGContextSetFillColorWithColor(ctx,[[UIColor redColor]CGColor]);CGFloat radius =self.radius;CGRect rect;rect.size = CGSizeMake(radius,radius);rect.origin.x = (self.bounds.size.width - radius)/2;rect.origin.y = (self.bounds.size.height - radius)/2;CGContextAddEllipseInRect(ctx,rect);CGContextFillPath(ctx);}+(BOOL)needsDisplayForKey:(NSString *)key{if([key isEqualToString:@"radius"]){return YES;}return [super needsDisplayForKey:key];}-(id<CAAction>)actionForKey:(NSString *)key{if([self presentationLayer] != nil){ if([key isEqualToString:@"radius"]) { CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath@"radius"]; anim.fromValue = [[self presentationLayer] valueForKey:@"radius"]; return animo; }}return [super actionForKey:key];}@end先来回顾以下基础知识。在init方法里调用setNeedsDisplay,这样图层的drawInContext会在第一次添加图层到图层树时被调用。覆盖needsDisplayForKey:方法,这样无论如何修改半径都可以自动重绘。
Core Animation为了生成动画效果会创建图层的多个副本。它使用initWithLayer:来实现复制,因此你需要实现这个方法来复制自定义的属性。
现在要修改动作了。我们实现了actionForKey:方法,一次返回一个在当前图(presentationLayer)中有半径起始值(fromValue)的动画。这意味如果动画中途变化,动画效果会更加平滑。
Core Animation 与线程
Core Animation可以很好的适应线程。通常,可以在任意线程中修改CALayer属性,这点与UIView属性不同。可以在任何线程中调用drawInContext:方法。(不过特定的CGContext只能一次在一个线程上修改。)对CALayer属性的更改会使用CATransaction按事务分配到多个线程中进行处理。如果有一个运行循环的话,这个过程就会自动发生;如果没有运行循环,则需要定期调用[CATransaction flush]。如果可能,应该在运行循环的线程中实现Core Animation动作来改善性能。
- Core Animation 五 (美化图层,用动作实现自定义动画、为自定义的属性添加动画以及线程)
- 自定义Animation动画,完成跑圈动作
- Core Animation--3.图层的内容动画
- Core Animation(五)显式动画
- Animation动画的解析与自定义Animation
- Core Animation动画学习2——自定义CALayer的动画
- Mecanim动画编辑器 - 添加动画层实现并行动作
- Android 自定义动画(Animation)
- Android自定义Animation动画
- Android自定义Animation动画
- 自定义ViewGroup、 动画Animation
- Android自定义Animation动画
- Android 自定义Animation动画
- 自定义动画Animation
- 继承Animation自定义动画
- Core Animation - 属性动画CAPropertyAnimation
- 自定义view+属性动画实现
- Android属性动画---Property Animation(五)
- Android RelativeLayout 属性
- 通过浏览器启动Android应用程序
- 关于LR场景中,最大响应时间与最小响应时间差距大的问题
- 得到的length和数据库中的字段的长度相同
- 外媒:这些数码产品过度炒作 目前不值得购买
- Core Animation 五 (美化图层,用动作实现自定义动画、为自定义的属性添加动画以及线程)
- java_集合体系之Map框架相关抽象类接口详解、源码——08
- 逻辑读,物理读,各种读 20131224
- X-CODE开发的基础设置!
- 【性能分析】oProfile的安装与使用
- yii-theme使用
- 2013资料整理-iOS内存管理机制
- 智能路由 为何引爆互联网巨头间的竞争?
- linux下 tar解压 gz解压 bz2等各种解压文件使用方法