UIView动画(过渡效果)的学习笔记
http://www.cnblogs.com/lovecode/archive/2011/11/05/2237077.html
http://geeklu.com/2012/09/animation-in-ios/
iOS开发系列--让你的应用“动”起来
********************************************
一,设计复杂的iOS动画效果的一些设计原理
如果一个类承担的职能过多,就等于把这些职能耦合在一起,一个职能的变化可能会削弱或者抑制其他职能的能力,这种耦合会导致脆弱的设计,当发生变化时,设计会遭到意想不到的破坏。如果想要避免这种现象发生,就要尽可能的遵守单一职能原则。
// 显示动画 - (void)showWithDuration:(CGFloat)duration animated:(BOOL)animated; // 隐藏动画 - (void)hideWithDuration:(CGFloat)duration animated:(BOOL)animated; // 创建view - (void)buildView; // 动画百分比(手动设置动画的程度) - (void)percent:(CGFloat)percent;
二 、使用maskView设计动画
首先是确定maskview和view的重叠范围 ,不重叠部分不显示;其次是透明度,透明部分不显示;
1、maskView(maskLayer)基本原理
1)蒙板的基本原理
mask——蒙板,是将不同灰度色值转化为不同的透明度,并作用到它所在的图层,使图层不同部位透明度产生相应的变化。黑色为完全透明,白色为完全不透明。
蒙版:
①它是一种特殊的选区,但它的目的并不是对选区进行操作,相反,而是要保护选区的不被操作。同时,不处于蒙板范围的地方则可以进行编辑与处理。
②蒙板虽然是种选区,但它跟常规的选区颇为不同。常规的选区表现了一种操作趋向,即将对所选区域进行处理;而蒙板却相反,它是对所选区域进行保护,让其免于操作,而对非掩盖的地方应用操作
2)png图片透明像素的原理 : 只有png图片才有透明遮罩效果,jpg的不行。
3)maskView(maskLayer)可类比于多张png图片的叠加遮罩,原理类似
4)maskView是iOS8以上才有的,如果要考虑兼容低版本,用maskLayer替换
// 底图 self.baseImageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, width, width)]; self.baseImageView.image = [UIImage imageNamed:@"base"]; [self.view addSubview:self.baseImageView]; // mask self.maskImageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20 + width + 20, width, width)]; self.maskImageView.image = [UIImage imageNamed:@"mask"]; [self.view addSubview:self.maskImageView]; // 使用maskView的情况 self.addImageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20 + (width + 20) * 2, width, width)]; [self.view addSubview:self.addImageView]; self.addImageView.image = [UIImage imageNamed:@"base"]; UIImageView *mask = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, width)]; mask.image = [UIImage imageNamed:@"mask"]; // maskView并不能用addSubview来添加遮罩,这点千万注意 self.addImageView.maskView = mask;
2、maskView配合CAGradientLayer的使用
// 加载图片 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 200, 200)]; imageView.image = [UIImage imageNamed:@"base"]; [self.view addSubview:imageView]; // 创建出CAGradientLayer CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.frame = imageView.bounds; gradientLayer.colors = @[(__bridge id)[UIColor clearColor].CGColor, (__bridge id)[UIColor blackColor].CGColor, (__bridge id)[UIColor clearColor].CGColor]; gradientLayer.locations = @[@(0.25), @(0.5), @(0.75)]; gradientLayer.startPoint = CGPointMake(0, 0); gradientLayer.endPoint = CGPointMake(1, 0); // 容器view --> 用于加载创建出的CAGradientLayer UIView *containerView = [[UIView alloc] initWithFrame:imageView.bounds]; [containerView.layer addSublayer:gradientLayer]; // 设定maskView imageView.maskView = containerView; CGRect frame = containerView.frame; frame.origin.x -= 200; // 重新赋值 containerView.frame = frame; // 给maskView做动画效果 [UIView animateWithDuration:3.f animations:^{ // 改变位移 CGRect frame = containerView.frame; frame.origin.x += 400; // 重新赋值 containerView.frame = frame; }];
效果如下图:
三,用缓动函数模拟物理动画
1、‣缓动函数简介
1)、缓动函数的动画效果是建立在CALayer层级的关键帧动画基础之上
2)、缓动函数是一系列模拟物理效果(如抛物线)方程式的统称,用以计算给定两点之间的插值
3)、两点之间插的值越多,效果越好,但是会耗费更多的性能
4)、只有理解了缓动函数的原理才有可能写出自己想要的效果
1)、关键帧动画需要提供很多的帧来完善动画效果
2)、关键帧动画的帧可以通过一定的数学计算来提供需要的帧数
3)、关键帧动画只需要提供起始点,结束点,就可以通过缓动函数来计算中间“缺失”的帧
4)、缓动函数可以指定计算出多少帧
5)、帧数越多,动画越流畅,但同时耗费更多的GPU性能
1)、使用easeOutElastic函数来创建弹簧效果
2)、将easeOutElastic创建出来的帧数组添加到关键帧动画中
3)、弹簧效果用途
1)、使用easeOutBounce函数来创建弹簧效果
2)、将easeOutBounce创建出来的帧数组添加到关键帧动画中
3)、碰撞效果用途
1)、使用easeOutCubic函数来创建弹簧效果
2)、将easeOutCubic创建出来的帧数组添加到关键帧动画中
3)、衰减效果用途