热点新闻
iOS 动画方法内容整理
2023-07-13 21:59  浏览:328  搜索引擎搜索“错改B2B”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在错改B2B看到的信息,谢谢。
展会发布 展会网站大全 报名观展合作 软文发布



Core Animation继承关系图.png

动画在UI交互中是一种增强用户体验的利器,目前看到几乎每一个移动App都会使用到各种动画效果。
在IOS开发中实现动画效果通常有三种方式。

  • 1、基于UIView,为了方便实现简单的动画封装的UIView Animation。
  • 2、基于CALayer的Core Animation框架,这是动画的基础框架。
  • 3、在游戏开发中经常用到的基于物理模拟的动画框架UIKit Dynamics。【未涉及,暂不讲解】

先放置了一个View测试 #define Size(x) ((x)*[[UIScreen mainScreen] bounds].size.width/375.f) #define kScreenHeight [[UIScreen mainScreen] bounds].size.height #define kScreenWidth [[UIScreen mainScreen] bounds].size.width @property (nonatomic, strong) UIView *greenView; -(void)initCusView{ self.greenView = [[UIView alloc]initWithframe:CGRectMake(0, Size(0), Size(100), Size(100))]; self.greenView.backgroundColor = UIColor.greenColor; [self.view addSubview:self.greenView]; }

UIView Animation

UIView Animation 参数说明: duration : 动画经历时长 delay : 延迟时间,在该延迟时间后才执行动画 options : 系统提供了许多动画执行的方式,比如以下几个 enum { //这部分是基础属性的设置 UIViewAnimationOptionLayoutSubviews = 1 << 0,//设置 子视图随父视图展示动画 UIViewAnimationOptionAllowUserInteraction = 1 << 1,//允许在动画执行时用户与其进行交互 UIViewAnimationOptionBeginFromCurrentState = 1 << 2,//允许在动画执行时执行新的动画 UIViewAnimationOptionRepeat = 1 << 3,//设置动画循环执行 UIViewAnimationOptionAutoreverse = 1 << 4,//设置动画反向执行,必须和重复执行一起使用 UIViewAnimationOptionOverrideInheritedDuration = 1 << 5,//强制动画使用内层动画的时间值 UIViewAnimationOptionOverrideInheritedCurve = 1 << 6,//强制动画使用内层动画曲线值 UIViewAnimationOptionAllowAnimatedContent = 1 << 7,//设置动画视图实时刷新 UIViewAnimationOptionShowHideTransitionViews = 1 << 8,//设置视图切换时隐藏,而不是移除 UIViewAnimationOptionOverrideInheritedOptions = 1 << 9,// //这部分属性设置动画播放的线性效果 UIViewAnimationOptionCurveEaseInOut = 0 << 16,//淡入淡出 首末减速 UIViewAnimationOptionCurveEaseIn = 1 << 16,//淡入 初始减速 UIViewAnimationOptionCurveEaseOut = 2 << 16,//淡出 末尾减速 UIViewAnimationOptionCurveLinear = 3 << 16,//线性 匀速执行 //这部分设置UIView切换效果(转场动画使用) UIViewAnimationOptionTransitionNone = 0 << 20, UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20,//从左边切入 UIViewAnimationOptionTransitionFlipFromRight = 2 << 20,//从右边切入 UIViewAnimationOptionTransitionCurlUp = 3 << 20,//从上面立体进入 UIViewAnimationOptionTransitionCurlDown = 4 << 20,//从下面立体进入 UIViewAnimationOptionTransitionCrossDissolve = 5 << 20,//溶解效果 UIViewAnimationOptionTransitionFlipFromTop = 6 << 20,//从上面切入 UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20,//从下面切入 }; animation : UIView动画结束时的状态 ( 比如 : UIView移动到另一点,变成某一种颜色,放大(缩小)后的比例,变化到某一透明度,视图旋转到某一角度) completion : 动画结束时的回调(这里可以处理一些事件) usingSpringWithDamping : 阻尼(弹性系数) initialSpringVelocity : 初始速率 ///基础动画,结束无回调 [UIView animateWithDuration:1 animations:^{ }]; ///基础动画,结束带回调 [UIView animateWithDuration:1 animations:^{ } completion:^(BOOL finished) { }]; ///进阶动画--带动画执行的方式,结束带回调 [UIView animateWithDuration:1 delay:1 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{ } completion:^(BOOL finished) { }]; ///进阶动画--可设置弹跳效果,结束带回调 带动画执行的方式 [UIView animateWithDuration:1 delay:1 usingSpringWithDamping:0.11 initialSpringVelocity:1 options:UIViewAnimationOptionAutoreverse animations:^{ } completion:^(BOOL finished) { }];

可以用来做什么呢:
设置UIView的属性:例如
frame
bounds
center
transform
alpha
backgroundColor
contentStretch

看一下实例:

self.greenView = [[UIView alloc]initWithframe:CGRectMake(Size(30), Size(100), Size(100), Size(100))]; self.greenView.backgroundColor = UIColor.greenColor; [self.view addSubview:self.greenView]; ///开始动画 -(void)startAnimation{ [UIView animateWithDuration:1 animations:^{ ///缩放比例 self.greenView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.5, 1.5); ///位置调整 CGRect rect = self.greenView.frame; rect.origin.x += Size(50); rect.origin.y += Size(50); self.greenView.frame = rect; ///透明度变化 self.greenView.alpha = 0.5; ///color变化 self.greenView.backgroundColor = UIColor.redColor; ///圆角改变 self.greenView.layer.cornerRadius = Size(50); self.greenView.clipsToBounds = YES; }]; }

我们可以看到self.greenView通过UIView Animation动画将某些属性进行了改变。

现在我们适当的加入一些动画执行的方式【options】

UIViewAnimationOptionRepeat:持续重复动画内容 UIViewAnimationOptionCurveEaseIn:淡入 UIViewAnimationOptionCurveEaseOut:淡出 UIViewAnimationOptionCurveEaseInOut:淡入淡出 UIViewAnimationOptionCurveLinear:匀速运动 [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ CGRect rect = self.greenView.frame; rect.origin.x += Size(275); self.greenView.frame = rect; } completion:^(BOOL finished) { }];


动画执行.gif

在开发中可以添加特定的options满足不同的动画需要。

弹簧效果:





弹簧效果.gif

[UIView animateWithDuration:3 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{ CGRect rect = self.greenView.frame; rect.origin.x += Size(275); self.greenView.frame = rect; } completion:^(BOOL finished) { }];

CABasicAnimation

CABasicAnimation 为layer属性提供了基础的帧动画能力,创建一个CABasicAnimation的实例,使用继承自CAPropertyAnimation的animationWithKeyPath:方法,来指定要添加动画的layer属性的keypath

CABasicAnimation常用的有如下几个属性: //动画改变属性 @property(nullable, copy) NSString *keyPath; // 指定执行动画layer的起始值 @property(nullable, strong) id fromValue; // 指定结束动画layer的结束值 @property(nullable, strong) id toValue; // 指定执行动画的时候的相对值 @property(nullable, strong) id byValue; CABasicAnimation 相关常用属性 @property float repeatCount; @property CFTimeInterval repeatDuration; @property CFTimeInterval duration; @property(getter=isRemovedOnCompletion) BOOL removedOnCompletion; @property(copy) NSString *fillMode; //设定动画的速度变化 默认:nil 使用写法:[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; @property(nullable, strong) CAMediaTimingFunction *timingFunction; //动画结束时执行逆动画 @property BOOL autoreverses;

CABasicAnimation的写法。
移动动画

让一个view向左平移,在x方向上从屏幕x中间线型移动到左边消失,耗时1.5秒的动画




移动动画.gif

第一种方法: // 创建动画 使用动画改变属性 position.x CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.x"]; // 指定基础动画的时间间隔,以秒为单位默认值是 0.25 positionAnima.duration = 1.5; //改变前的属性 positionAnima.fromValue = @((kScreenWidth-Size(100))/2); //改变后的属性 positionAnima.toValue = @(-self.greenView.frame.size.width / 2); //保存最新状态 positionAnima.fillMode = kCAFillModeForwards; //动画组件不被移除 positionAnima.removedonCompletion = NO; [self.greenView.layer addAnimation:positionAnima forKey:@"position.x"]; 第二种方法: // 创建动画 CABasicAnimation *positionAnima = [CABasicAnimation animation]; // 动画改变属性 positionAnima.keyPath = @"position"; positionAnima.duration = 1.5; // 改变后的属性 positionAnima.toValue = [NSValue valueWithCGPoint:CGPointMake(-Size(50), Size(100+50))]; // 动画组件不被移除 positionAnima.removedonCompletion = NO; // 保存最新状态 positionAnima.fillMode = kCAFillModeForwards; [self.greenView.layer addAnimation:positionAnima forKey:@"position"]; 区别:设置的keypath不同第一种方法指定了左移,第二种方法可以是上下左右移动,fromValue、toValue需要根据keypath属性改变

旋转动画

5s完成旋转一周的顺时针旋转的view 并持续旋转 CABasicAnimation * rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 ]; rotationAnimation.duration = 5; rotationAnimation.cumulative = YES; rotationAnimation.repeatCount = HUGE_VAL; rotationAnimation.removedonCompletion = NO; [self.greenView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];

缩放动画

// 设定为缩放 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; // 动画选项设定 animation.duration = 2.5; // 动画持续时间 animation.repeatCount = 1; // 重复次数 animation.autoreverses = YES; // 动画结束时执行逆动画 // 缩放倍数 animation.fromValue = [NSNumber numberWithFloat:1.0]; // 开始时的倍率 animation.toValue = [NSNumber numberWithFloat:2.0]; // 结束时的倍率 // 添加动画 [self.greenView.layer addAnimation:animation forKey:@"scale-layer"];

KeyPath的改变动画的效果就不一样,开发中改变KeyPath的属性可以实现大多数我们需要的动画执行的效果

animationWithKeyPath值类型:

position = 路径(一般用CAKeyframeAnimation) transform.rotation = 旋转 transform.rotation.x = x旋转 transform.rotation.y = y旋转 transform.rotation.z = z旋转(顺逆时针) transform.translation = 平移 transform.translation.x = x平移 transform.translation.y = y平移 transform.scale = 比例转换 transform.scale.x = x的比例转换 transform.scale.y = y的比例转换 transform.scale.y = y的比例转换 transform.rotation.z = 平面圆的转换 opacity = 透明度 margin zPosition backgroundColor = 背景颜色 cornerRadius = 圆角 borderWidth bounds contents contentsRect cornerRadius frame 坐标 hidden 隐藏 mask masksToBounds shadowColor shadowOffset shadowOpacity shadowRadius 大家可以尝试使用不同的keypath看看动画效果

用CABasicAnimation执行动画,在动画结束后会回归动画开始前的状态。想要解决的话,必须设置“removedOnCompletion”和“fillMode”这两个属性。

// 动画终了后不返回初始状态 animation.removedonCompletion = NO; animation.fillMode = kCAFillModeForwards;

但是

由于在开发过程中光是CABasicAnimation的fromValue、toValue起点和终点设置是无法满足我们希望在动画中途进行更多的变化的需求,所以我们需要认识一下CAKeyframeAnimation

CAKeyframeAnimation[关键帧动画]

从上面的继承图我们看出CAKeyframeAnimation 比CABasicAnimation多了更多的可设置属性

@property(nullable, copy) NSArray *values; @property(nullable) CGPathRef path; @property(nullable, copy) NSArray*keyTimes; @property(nullable, copy) NSArray*timingFunctions; @property(copy) NSString *calculationMode; @property(nullable, copy) NSArray*tensionValues; @property(nullable, copy) NSArray*continuityValues; @property(nullable, copy) NSArray *biasValues; @property(nullable, copy) NSString *rotationMode;

关键帧动画其实通过一组动画类型的值(或者一个指定的路径)和这些值对应的时间节点以及各时间节点的过渡方式来控制显示的动画。关键帧动画可以通过path属性和values属性来设置动画的关键帧。

通过path设置动画



关键帧-path.gif

绕线一周动画 CGMutablePathRef path = CGPathCreateMutable(); //第一个关键帧 -100,-100 CGPathMoveToPoint(path, NULL, 0, 0); //第二个关键帧 100,-100 CGPathAddLineToPoint(path, NULL, 100, 0); //第三个关键帧 100,100 CGPathAddLineToPoint(path, NULL, 100, 100); //第四个关键帧 -100,100 CGPathAddLineToPoint(path, NULL, 0, 100); //第五个关键帧 -100,-100 CGPathAddLineToPoint(path, NULL, 0, 0); CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; animation.keyPath = @"transform.translation"; animation.path = path; animation.duration = 4; animation.keyTimes = @[@(0),@(0.1),@(0.5),@(0.75),@(1)]; animation.timingFunctions = @[[CAMediaTimingFunction functionWithControlPoints:1 :0.5 :0.5 :0.5], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]]; //动画结束后保持动画最后的状态,两个属性需配合使用 animation.removedonCompletion = NO; animation.fillMode = kCAFillModeForwards; CGPathRelease(path); [self.greenView.layer addAnimation:animation forKey:@""];

通过values设置动画



关键帧-values.gif

/// 放大缩小放大缩小【隐藏】 CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; animation.duration = 2.0;// 动画时间 animation.removedonCompletion = NO; animation.values = @[@1,@1.2,@1,@1.2,@0]; //动画结束后保持动画最后的状态,两个属性需配合使用 animation.removedonCompletion = NO; animation.fillMode = kCAFillModeForwards; [self.greenView.layer addAnimation:animation forKey:nil];

CAAnimationGroup[动画组]

可以保存一组动画CAKeyframeAnimation、CABasicAnimation对象,将CAAnimationGroup对象加入图层后,组中所有动画对象可以同时并发运行。

购物车动画



动画组.gif

CABasicAnimation *animation1 = [CABasicAnimation animationWithKeyPath:@"transform.translation"]; // 终点设定 animation1.toValue = [NSValue valueWithCGPoint:CGPointMake(kScreenWidth-Size(50), kScreenHeight-Size(50))]; // 終点 CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; // 设定旋转角度 animation2.fromValue = [NSNumber numberWithFloat:0.0]; // 开始时的角度 animation2.toValue = [NSNumber numberWithFloat:4 * M_PI]; // 结束时的角度 CAAnimationGroup *group = [CAAnimationGroup animation]; // 动画选项设定 group.duration = 3.0; group.repeatCount = 1; // 添加动画 group.animations = [NSArray arrayWithObjects:animation1, animation2, nil]; [self.greenView.layer addAnimation:group forKey:@"move-rotate-layer"];

注意:默认情况下,一组动画对象是同时运行的,也可以通过设置单个动画对象的beginTime属性来更改动画的开始时间,单个动画的执行效果可以与动画组执行效果属性分开设定,根据需要调整改变。

发布人:813a****    IP:125.64.38.***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发