• iOS动画技术笔记


    概述

    在IOS开发中,实现动画操作的地方有很多,典型的是在视图控制器的segue操作时。在同一个视图控制器类中,加载切换不同的视图时,也需要动画效果,还有一些视图对象有动画效果会更好。

    插一句,在IOS开发过程中,感觉自己就像一个导演在工作,安排不同的布景,不同的画面切换。应用有了流畅的画面,会增色不少。

    在storyboard中创建视图和视图控制器时,会有一些动画设置。但在代码角度上,我们还是需要理解一下这个动画设置的实现过程。

    动画实现在不同的视图控制器切换操作时如presentViewController或popViewController时,使用的是CATransition。

    CATransition其实也是基于layer的实现,用于切换不同的视图,但它能实现的效果有限。例如,不能满足两个视图控制器的视图在一个windows上展现的动画。我是想使用panGestureController实现来自于两个视图控制器的视图动画显示效果,这点很遗憾。

    在同一视图控制器上的不同视图的动画切换,可以使用UIView 的beginAnimations:nil 或animateWithDuration:animations:completion:等方法来实现。

    动画实现也就是通过修改视图一些属性,在设定时间能反复或逐步完成这些修改操作,达到动画展现的效果。

    这些属性如下所示:

    1.frame,bounds,center//改变View的frame属性

    2.alpha //改变透明度

    3.backgroundColor//改变背景颜色

    4.contentStretch//拉伸变化

    5.transform//仿射变换,其中又包括Rotate,Invert,Translate,Scale(旋转,反转,位移,缩放)

    普通的动画都是30帧每秒,肉眼能识别的是24帧每秒,而在游戏上会要求是60帧每秒。

    这些视图就是在设置的时间内,根据时间函数如缓入、缓出等,修改它的这些属性。修改一次,变成一个,周而复始。在我们肉眼看来,这就是一个连续的动作,就是动画。

    这里说到UIView的属性,就不能不说它的组成。UIView其实是由layer组成的。UIView的这些属性如bounds,center都是来自于CALayer的对象。

    在视图的layer上,将CAAnimation的对象添加进来就能实现视图的动画效果。CAAnimation是一个抽象类,它的实体类有CABasicAnimation 和CAKeyframeAnimation 。

    通过CABasicAnimation或CAKeyframeAnimation 对象的定义,将它加入到UIView.layer中去,实现动画效果。注意,动画完成后,layer的属性定义又恢复到初始值。如果要保存动画结果,那么需要在添加动画到layer时做约定设置。

    例如,在一个视图中加一个UIImage对象,声明一个CALayer的图层对象,将该图层的contents设置为UIImage对象的CGImage,然后在这个图层对象做处理。

    首先,声明一个CABasicAnimation的对象scaleAnimation的keyPath为transform.scale。

    CABasicAnimation *scaleAnimation = [CABasicAnimationanimationWithKeyPath:@"transform.scale"];

    然后,设置keyPath的值,动画执行时间,动画执行时间函数。如果需要在动画结束后将结果保存下来,则需要在delegate的方法- (void)animationDidStop:(CAAnimation*)theAnimation finished:(BOOL)flag中去实现。

       scaleAnimation.toValue =scaleFactor;

       scaleAnimation.duration =3.0f;

       scaleAnimation.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    最后,将CABasicAnimation的对象scaleAnimation加到图层中去,剩下就由IOS自己去实现,代码上就到这一步了。

       [self.view.layeraddSublayer:logoLayer];

    详细的代码如下

    - (void)viewDidLoad {

       [super viewDidLoad];

      

       self.view.backgroundColor =[UIColor blackColor];

       self.title = [[self class]displayName];

      

       UIImage *image = [UIImageimageNamed:@"batman.png"];

       logoLayer = [CALayer layer];

       logoLayer.bounds =CGRectMake(0, 0, image.size.width, image.size.height);

       logoLayer.position =CGPointMake(160, 180);

       logoLayer.contents =(id)image.CGImage;

      

       // Add layer as a sublayerof the UIView's layer

       [self.view.layeraddSublayer:logoLayer];

    }

    - (void)scaleByFactor:(CGFloat)factor {

       CABasicAnimation*scaleAnimation = [CABasicAnimationanimationWithKeyPath:@"transform.scale"];

        NSNumber *scaleFactor =[NSNumber numberWithFloat:factor];

       scaleAnimation.toValue =scaleFactor;

       scaleAnimation.duration =3.0f;

       scaleAnimation.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

        // Set the model layer'sproperty so the animation sticks at the 'toValue' state

       [logoLayer addAnimation:scaleAnimationforKey:@"transformAnimation"];

    }

    这里动画效果还只是针对一个视图对象的,如果需要多个视图同时操作,则需要实现动画联动,也就是CAAnimationGroup。将多个CABasicAnimation对象就加到一个数组中,再将这个数组设置到CAAnimationGroup的对象中,最后将CAAnimationGroup的对象加到图层的动画属性中。

       CAAnimationGroup*animationGroup = [CAAnimationGroup animation];

       animationGroup.duration =2.0f;

       animationGroup.autoreverses= YES;

       animationGroup.repeatCount =HUGE_VALF;

       [animationGroupsetAnimations:[NSArray arrayWithObjects:rotationAnimation, scaleAnimation,nil]];

     

       [logoLayeraddAnimation:animationGroup forKey:@"animationGroup"];

    如果需要在图层上更精细的设置,那么需要CALayer上做扩展,形成各种各样的子类。

    CALayer的子类有:

    1)  CAScrollLayer,用于简化显示层的一部分

    2)  CATextLayer,便于从字符串生成内容是文本的层

    3)  CATiledLayer,可用于显示复杂的图片

    4)  CAOpenGLLayer,提供OpenGLES渲染环境

     CALayer能够对 UIView 做许多设定,如:阴影、边框、圆角和透明效果等,且这些设定都是很有用的。它的重要属性如下。 

    1. shadowPath :设置 CALayer 背景(shodow)的位置 

    2. shadowOffset :shadow 在 X 和 Y 轴 上延伸的方向,即shadow 的大小 

    3. shadowOpacity: shadow 的透明效果 

    4. shadowRadius :shadow 的渐变距离,从外围开始,往里渐变 shadowRadius 距离 

    5. masksToBounds: 很重要的属性,可以用此属性来防止子元素大小溢出父元素,如若防止溢出,请设为 true 

    6.borderWidth 和 boarderColor : 边框颜色和宽度,很常用 

    7. bounds :对于我来说比较难的一个属性,测了半天也没完全了解,只知道可以用来控制UIView 的大小,但是不能控制 位置 

    8. opacity :UIView 的透明效果 

    9. cornerRadius :UIView 的圆角

    这些属性和UIView的属性很像,可以实现UIView实现不了的效果。

    其实,我觉得UIKIT中声明的那么组件如UITextfield,uilable,uibutton,其实就是UIView的扩展,封装好了方便使用而已。

    总结

    在IOS中动画效果从layer层开始,向layer中添加CABasicAnimation对象,实际上就是layer中有一个预定义的功能,在视图viewDidAppear后就会执行这个功能点。

    可能是因为CABasicAnimation稍微复杂点,IOS又封装出来一个类CATransition,它实现的功能有限,一些基本的动画操作如

    可能是从方便使用的角度考虑,IOS又对UIView做了可做,有了beginAnimations:nil或animateWithDuration:animations:completion:等方法,可更方便地实现一些动画效果。

    但是,如果要实现复杂的,更吸引人的动画,还需要在CALayer上下功夫。

  • 相关阅读:
    eclipse中怎么修改所复制的web项目的部署名字
    javax.servlet.jsp.JspException cannot be resolved to a type异常信息
    如何修改maven本地仓库位置
    如何让plsql连接64位oracle数据库
    JavaWeb: 报错信息The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    解决eclipse spring-MVC配置报错:cvc-elt.1: Cannot find the declaration of element 'beans'.
    jdk环境变量配置
    12. Mysql基础入门
    11. Linux从入门到进阶
    PC、APP、H5三端测试的相同与不同
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3212006.html
Copyright © 2020-2023  润新知