iOS 动画给人一种很流畅的感觉,提升用户体验,在APP开发过程中,我们只要利用好系统的动画,基本可以解决大部分的需求。
UIView动画实质上是Core Animation的封装,系统提供简洁的动画接口。
其中UIView动画可以设置的属性有:
- frame 大小
- bounds 拉伸
- center 中心位置
- transform 旋转
- alpha 透明度
- backgroundColor 背景色
- contentStretch 拉伸内容
UIView类动画
API
/// 动画开始标记
/// 第一个参数:动画标识
/// 附加参数,在设置了代理的情况下,此参数将发送到setAnimationWillStartSelector和setAnimationDidStopSelector所指定的方法。大部分情况下,我们设置为nil即可。
[UIView beginAnimations:(nullable NSString *)animationID context:(nullable void *)context]
/// 动画持续时间
[UIView setAnimationDuration:(NSTimeInterval)];
/// 动画代理设置
[UIView setAnimationDelegate:(nullable id)];
/// 设置动画开始执行的回调SEL
[UIView setAnimationWillStartSelector:(nullable SEL)];
/// 设置动画执行结束的的回调SEL
[UIView setAnimationDidStopSelector:(nullable SEL)];
/// 设置动画延迟执行的时间
[UIView setAnimationDelay:(NSTimeInterval)];
/// 设置动画执行的重复次数
[UIView setAnimationRepeatCount:(float)];
/// 设置动画过渡曲线
[UIView setAnimationCurve:(UIViewAnimationCurve)];
UIViewAnimationCurve是一个枚举:
UIViewAnimationCurveEaseInOut, //缓入缓出 中间快
UIViewAnimationCurveEaseIn, // 由慢到快(缓入快出)
UIViewAnimationCurveEaseOut, // 由快到慢(快入缓出)
UIViewAnimationCurveLinear, // 匀速
/// 设置是否从当前状态开始播放
/// 假设上一个动画正在播放,且未播放完成, 我们将要执行新的动画.
/// 当YES时,动画将从上一个动画所在的状态开始播放
/// 当NO时,动画将从上一个动画所指定的最终状态开始播放(此时上一个动画马上结束)
[UIView setAnimationBeginsFromCurrentState:YES];
/// 动画是否继续执行相反的动画
[UIView setAnimationRepeatAutoreverses:(BOOL)];
/// 是否禁用动画效果(对象属性依然会该拜年,只是没有动画过渡效果)
[UIView setAnimationsEnabled:(BOOL)];
/// 设置视图过渡效果
[UIView setAnimationTransition:(UIViewAnimationTransition) forView:(nonnull UIView *) cache:(BOOL)];
/*
第一个参数: UIViewAnimationTransition,是一个枚举
UIViewAnimationTransitionNone, // 不使用动画
UIViewAnimationTransitionFlipFromLeft, // 从左向右旋转翻页
UIViewAnimationTransitionFlipFromRight, // 从右向左旋转翻页
UIViewAnimationTransitionCurlUp, // 从下往上卷曲翻页
UIViewAnimationTransitionCurlDown, // 从上往下卷曲翻页
第二个参数:需要知心过渡动画的view
第三个参数:是否使用视图缓存,YES:视图在开始和结束时渲染一次,NO:视图在每一帧都渲染
*/
实例展示
- 改变属性frame
- (void)animation1{
[UIView beginAnimations:@"FrameAnimation" context:@"232323"];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationWillStartSelector:@selector(startAnimation:context:)];
[UIView setAnimationDidStopSelector:@selector(stopAnimation:)];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
self.giftView.frame = self.heartView.frame;
[UIView commitAnimations];
}
//返回context参数
- (void)startAnimation:(NSString *)aniID context:(NSString *)context{
}
- (void)startAnimation:(NSString *)aniID{
NSLog(@"%@",aniID);
}
- (void)stopAnimation:(NSString *)aniID{
NSLog(@"%@",aniID);
}
效果图
- 转场效果动画
//转场动画
- (void)transitions{
[UIView beginAnimations:@"FlipAni" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationWillStartSelector:@selector(startAnimation:)];
[UIView setAnimationDidStopSelector:@selector(stopAnimation:)];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.giftView cache:NO];
self.giftView.image = [UIImage imageNamed:@"local_2"];
[UIView commitAnimations];
}
效果图
UIView Block动画
- UIView BLock动画方法,都是比较常用的方法
[UIView animateWithDuration:(NSTimeInterval) //动画持续时间
animations:^{
//执行的动画
}];
[UIView animateWithDuration:(NSTimeInterval) //动画持续时间
animations:^{
//执行的动画
} completion:^(BOOL finished) {
//动画执行完毕后的操作
}];
[UIView animateWithDuration:(NSTimeInterval) //动画持续时间
delay:(NSTimeInterval) //动画延迟执行的时间
options:(UIViewAnimationOptions) //动画的过渡效果
animations:^{
//执行的动画
} completion:^(BOOL finished) {
//动画执行完毕后的操作
}];
我们详细说一下UIViewAnimationOptions这个枚举值,可以参考iOS动画中的枚举UIViewAnimationOptions
UIViewAnimationOptionLayoutSubviews //提交动画的时候布局子控件,表示子控件将和父控件一同动画。
UIViewAnimationOptionAllowUserInteraction //动画时允许用户交流,比如触摸
UIViewAnimationOptionBeginFromCurrentState //从当前状态开始动画
UIViewAnimationOptionRepeat //动画无限重复
UIViewAnimationOptionAutoreverse //执行动画回路,前提是设置动画无限重复
UIViewAnimationOptionOverrideInheritedDuration //忽略外层动画嵌套的执行时间
UIViewAnimationOptionOverrideInheritedCurve //忽略外层动画嵌套的时间变化曲线
UIViewAnimationOptionAllowAnimatedContent //通过改变属性和重绘实现动画效果,如果key没有提交动画将使用快照
UIViewAnimationOptionShowHideTransitionViews //用显隐的方式替代添加移除图层的动画效果
UIViewAnimationOptionOverrideInheritedOptions //忽略嵌套继承的选项
//时间函数曲线相关
UIViewAnimationOptionCurveEaseInOut //时间曲线函数,缓入缓出,中间快
UIViewAnimationOptionCurveEaseIn //时间曲线函数,由慢到特别快(缓入快出)
UIViewAnimationOptionCurveEaseOut //时间曲线函数,由快到慢(快入缓出)
UIViewAnimationOptionCurveLinear //时间曲线函数,匀速
//转场动画相关的
UIViewAnimationOptionTransitionNone //无转场动画
UIViewAnimationOptionTransitionFlipFromLeft //转场从左翻转
UIViewAnimationOptionTransitionFlipFromRight //转场从右翻转
UIViewAnimationOptionTransitionCurlUp //上卷转场
UIViewAnimationOptionTransitionCurlDown //下卷转场
UIViewAnimationOptionTransitionCrossDissolve //转场交叉消失
UIViewAnimationOptionTransitionFlipFromTop //转场从上翻转
UIViewAnimationOptionTransitionFlipFromBottom //转场从下翻转
- Spring Block Animation
适用于所有可被添加动画效果的属性
[UIView animateWithDuration:(NSTimeInterval)//动画持续时间
delay:(NSTimeInterval)//动画延迟执行的时间
usingSpringWithDamping:(CGFloat)//阻尼系数,范围0~1,数值越小震动效果越明显
initialSpringVelocity:(CGFloat)//初始速度,数值越大初始速度越快
options:(UIViewAnimationOptions)//动画的过渡效果
animations:^{
//执行的动画
}
completion:^(BOOL finished) {
//动画执行完毕后的操作
}];
- Keyframes动画
iOS7新增关键帧动画,支持属性关键帧,不支持路径关键帧
[UIView animateKeyframesWithDuration:(NSTimeInterval)//动画持续时间
delay:(NSTimeInterval)//动画延迟执行的时间
options:(UIViewKeyframeAnimationOptions)//动画的过渡效果
animations:^{
//执行的关键帧动画
}
completion:^(BOOL finished) {
//动画执行完毕后的操作
}];
UIViewKeyframeAnimationOptions枚举(可以组合使用):
UIViewAnimationOptionLayoutSubviews //进行动画时布局子控件
UIViewAnimationOptionAllowUserInteraction //进行动画时允许用户交互
UIViewAnimationOptionBeginFromCurrentState //从当前状态开始动画
UIViewAnimationOptionRepeat //无限重复执行动画
UIViewAnimationOptionAutoreverse //执行动画回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套动画的执行时间设置
UIViewAnimationOptionOverrideInheritedOptions //不继承父动画设置
UIViewKeyframeAnimationOptionCalculationModeLinear //运算模式 :连续
UIViewKeyframeAnimationOptionCalculationModeDiscrete //运算模式 :离散
UIViewKeyframeAnimationOptionCalculationModePaced //运算模式 :均匀执行
UIViewKeyframeAnimationOptionCalculationModeCubic //运算模式 :平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced //运算模式 :平滑均匀
增加关键帧的方法:
[UIView addKeyframeWithRelativeStartTime:(double)//动画开始的时间(占总时间的比例)
relativeDuration:(double) //动画持续时间(占总时间的比例)
animations:^{
//执行的动画
}];
- 转场动画
4.1 从旧视图转到新视图的动画效果
[UIView transitionFromView:(nonnull UIView *)
toView:(nonnull UIView *)
duration:(NSTimeInterval)
options:(UIViewAnimationOptions)
completion:^(BOOL finished) {
//动画执行完毕后的操作
}];
在该动画执行过程中,fromView会从父视图移除,并将toView添加到父视图中,该转场动画作用对象是父视图
。(也就是说过渡动画体现在父视图上面)
调用该方法相当于调用下面两个方法:
[fromView.superview addSubview:toView];
[fromView removeFromSuperview];
4.2 单个视图的过渡动画
[UIView transitionWithView:(nonnull UIView *) //动画作用的对象
duration:(NSTimeInterval) //动画执行时间
options:(UIViewAnimationOptions) //动画过渡效果
animations:^{
//执行的动画
}
completion:^(BOOL finished) {
//动画执行完毕后的操作
}];
示例演示
- 改变frame位置
- (void)blockAnimation1{
[UIView animateWithDuration:1 animations:^{
self.giftView.frame = self.heartView.frame;
}completion:^(BOOL finished) {
NSLog(@"执行完毕");
}];
}
- (void)blockAnimation2{
[UIView animateWithDuration:0.5 delay:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.giftView.frame = self.heartView.frame;
} completion:^(BOOL finished) {
NSLog(@"执行完毕");
}];
}
动画效果:
- 阻尼动画
- (void)blockAni1{
[UIView animateWithDuration:1 delay:1 usingSpringWithDamping:0.5 initialSpringVelocity:5.0 options:UIViewAnimationOptionCurveLinear animations:^{
self.giftView.frame = self.heartView.frame;
} completion:^(BOOL finished) {
NSLog(@"执行结束");
}];
}
动画效果:
- Keyframes
这里以颜色变化为例,演示关键帧动画
- (void)blockAni2{
self.giftView.image = nil;
[UIView animateKeyframesWithDuration:9.0 delay:0.f options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
[UIView addKeyframeWithRelativeStartTime:0.f relativeDuration:1.0 / 4 animations:^{
self.giftView.backgroundColor = [UIColor colorWithRed:0.9475 green:0.1921 blue:0.1746 alpha:1.0];
}];
[UIView addKeyframeWithRelativeStartTime:1.0 / 4 relativeDuration:1.0 / 4 animations:^{
self.giftView.backgroundColor = [UIColor colorWithRed:0.1064 green:0.6052 blue:0.0334 alpha:1.0];
}];
[UIView addKeyframeWithRelativeStartTime:2.0 / 4 relativeDuration:1.0 / 4 animations:^{
self.giftView.backgroundColor = [UIColor colorWithRed:0.1366 green:0.3017 blue:0.8411 alpha:1.0];
}];
[UIView addKeyframeWithRelativeStartTime:3.0 / 4 relativeDuration:1.0 / 4 animations:^{
self.giftView.backgroundColor = [UIColor colorWithRed:0.619 green:0.037 blue:0.6719 alpha:1.0];
}];
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
动画效果
- 转场动画
4.1 单个视图的过渡效果
- (void)blockAni3{
[UIView transitionWithView:self.giftView duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
self.giftView.image = [UIImage imageNamed:@"local_2"];
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
执行效果
将枚举值换为UIViewAnimationOptionTransitionFlipFromLeft
的执行效果为:
4.2 从旧视图转到新视图的动画效果
//转场动画 从旧视图转到新视图的动画效果
- (void)blockAni4{
UIImageView * newCenterShow = [[UIImageView alloc]initWithFrame:self.giftView.frame];
newCenterShow.image = [UIImage imageNamed:@"local_2"];
[UIView transitionFromView:self.giftView toView:newCenterShow duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
该动画作用的是父视图,动画效果如下:
本文文章以及代码,参考了iOS动画篇:UIView动画,所有代码和动画我都验证过,截图是我自己做的。