1、视图动画(UIViewAnimation)
可以改变视图的属性(Animatable UIView properties)
frame:控制UIView的大小和该UIView在superview中的相对位置。
bounds:控制UIView的大小
center:控制UIView的位置
transform:控制UIView的缩放,旋转角度等固定好中心位置之后的变化
alpha:控制UIView的透明度
backgroundColor:控制UIView的背景色
contentStretch:控制UIView的拉伸方式
UIViewAnimateOptions
动画控相关
LayoutSubViews:提交动画时布局子控件,表示子控件将和父控件一同动画。
AllowUserInteraction:动画时允许用户交流,比如触摸
BeginFromCurrentState:从当前状态开始动画
Repeat:动画无限重复
Autoreverse:执行动画回路,前提是设置动画无限重复
OverrideInheritedDuration:忽略外层动画嵌套的执行时间
OverrideInheritedCurve:忽略外层动画嵌套的时间变化曲线
AllowAnimatedContent:通过改变属性和重绘实现动画效果,如果key没有提交动画将使用快照
ShowHideTransitionViews:用显隐的方式替代添加移除图层的动画效果
OverrideInheritedOptions:忽略嵌套继承的选项
时间曲线相关
CurveEaseIn:由慢到特别快
CurveEaseInOut:由慢到快
CurveEaseOut:由快到慢
CurveLinear:匀速
转场效果相关
TransitionNone //无转场动画
TransitionFlipFromLeft //转场从左翻转
TransitionFlipFromRight //转场从右翻转
TransitionCurlUp //上卷转场
TransitionCurlDown //下卷转场
TransitionCrossDissolve //转场交叉消失
TransitionFlipFromTop //转场从上翻转
TransitionFlipFromBottom //转场从下翻转
使用动画操作视图属性的方式:
1、Block,可以在一个动画块中操作多个view,当操作开始执行的时候,会开启新的线程去操作这些view,避免阻塞主线程。
- (void)basicAnimate { [UIView animateWithDuration:1 animations:^{ CGRect frame = self.firstView.frame; frame.origin.x += 100; [self.firstView setFrame:frame]; }]; } - (void)optionAnimate { [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse |UIViewAnimationOptionCurveLinear animations:^{
CGRect frame =self.firstView.frame; frame.origin.x += 100; self.firstView.frame = frame;
} completion:^(BOOL finished) { NSLog(@"finished=%d",finished); }]; } |
2、Begin/Commit
使用AnimationDelegate
- (void)beginCommitAnimate { //1、声明动画开始并配置动画属性 [UIView beginAnimations:@"testAnimate" context:nil]; [UIView setAnimationDuration:2.0]; [UIView setAnimationRepeatAutoreverses:YES]; [UIView setAnimationRepeatCount:10]; [UIView setAnimationDelegate:self]; [UIView setAnimationWillStartSelector:@selector(animationDidStart:)]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:)];
//2、操作视图 self.firstView.backgroundColor = [UIColor magentaColor]; //3、提交动画 [UIView commitAnimations]; } |
3、Nest(嵌套)方式
默认继承Parent Block的duration、curve等属性,内层设置的属性不起效。
使用以下三个属性修改:
OverideInheritedCurve
OverideInheritedDuration
OverideInheritedOptions
- (void)optionAnimate { [UIView animateWithDuration:2 delay:0 options://UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse | UIViewAnimationOptionCurveLinear animations:^{
CGRect frame =self.firstView.frame; frame.origin.x += 100; self.firstView.frame = frame;
//内层animate [UIView animateWithDuration:2.0 delay:0.0 options: UIViewAnimationOptionOverrideInheritedDuration | UIViewAnimationOptionOverrideInheritedCurve|UIViewAnimationOptionCurveEaseOut animations:^{ CGRect frame = self.secondView.frame; frame.origin.x += 100; self.secondView.frame = frame; } completion:^(BOOL finished) { NSLog(@"inner animate finished"); }];
} completion:^(BOOL finished) { NSLog(@"outer animate finished=%d",finished); }]; } |
使用动画进行视图过渡:
1、操作SubView
- (void)operateSubView { [UIView transitionWithView:self.firstView duration:2.0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationOptionAllowAnimatedContent animations:^{ CGRect frame = self.firstSubView.frame; frame.origin.x += 100; self.firstSubView.frame = frame;
// self.firstSubView.hidden = YES; } completion:^(BOOL finished) { NSLog(@"finished!"); }]; } |
2、替换View
- (void)replaceView { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(50, 400, 168, 89)]; view.backgroundColor = [UIColor magentaColor]; [UIView transitionFromView:self.secondView toView:view duration:2.0 options:UIViewAnimationOptionTransitionCurlUp|UIViewAnimationOptionAllowAnimatedContent completion:^(BOOL finished) { NSLog(@"finished"); }]; } |
2、核心动画(CoreAnimation)
什么是核心动画
图层CALayer(演员 )
什么是Layer? 每个view都有一个layer,所有的动画都发生在layer层,layer只负责内容显示,view还负责事件响应。view是一种特殊的layer,增加了事件响应等功能。 self.view.layer
创建和获取Layer
- (void)testLayerProperty { CALayer *myLayer = [[CALayer alloc] init]; myLayer.backgroundColor = [UIColor magentaColor].CGColor; myLayer.frame = CGRectMake(100, 100, 100, 100); // self.view.layer //要将layer显示出来,需要将Layer添加到view中 [self.view.layer addSublayer:myLayer]; } |
Layer和SubLayer
Layer属性
BackgroundColor/Border
Corner Radius
Shadow
...
- (void)testLayerProperty { CALayer *myLayer = [[CALayer alloc] init]; myLayer.backgroundColor = [UIColor magentaColor].CGColor; myLayer.frame = CGRectMake(100, 100, 100, 100); myLayer.borderColor = [UIColor blueColor].CGColor; myLayer.borderWidth = 5.0; myLayer.cornerRadius = 10.0; myLayer.shadowColor = [UIColor greenColor].CGColor; myLayer.shadowOffset = CGSizeMake(25.0, 25.0); myLayer.shadowOpacity = 0.2; // self.view.layer //要将layer显示出来,需要将Layer添加到view中 [self.view.layer addSublayer:myLayer]; } |
动画类CAAnimation(剧本)
CAAnimation
->CAMediaTiming
->CAAnimationGroup(animations)
->CAPropertyAnimation (keyPath、additive、cumulative)
->CABasicAnimation(fromValue、toValue、byValue)
->CAKeyframeAnimation(values、path、keyTimes、timingFunctions、calculationMode)
->CATransition(type、subtype、startProgress、endProgress、filter)
timingFunction delegate
隐式动画:直接修改属性执行的动画
- (void)implicitAnimate { CGPoint position = self.myLayer.position; position.y += 100; self.myLayer.position = position; } |
显示动画
- (void)caBasicAnimate { UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"test1"]]; //192 × 168 pixels imgView.frame = CGRectMake(150, 300, 192/2, 168/2); [self.view addSubview:imgView];
//给layer添加动画 CALayer *la = imgView.layer;
CABasicAnimation *scaleAni = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scaleAni.fromValue = [NSNumber numberWithDouble:1.0]; scaleAni.toValue = [NSNumber numberWithDouble:1.2]; scaleAni.autoreverses = YES; scaleAni.fillMode = kCAFillModeForwards; scaleAni.repeatCount = MAXFLOAT; scaleAni.duration = 1.0;
CABasicAnimation *opacityAni = [CABasicAnimation animationWithKeyPath:@"opacity"]; opacityAni.fromValue = [NSNumber numberWithDouble:.3]; opacityAni.toValue = [NSNumber numberWithDouble:1.0]; opacityAni.fillMode = kCAFillModeForwards; opacityAni.duration = 1.0; opacityAni.autoreverses = YES; opacityAni.repeatCount = MAXFLOAT;
[la addAnimation:scaleAni forKey:@"group"]; [la addAnimation:opacityAni forKey:@"opa"]; } |
animationWithKeyPath的值:
transform的KeyPath:
transform.scale = 比例转换
transform.scale.x = 宽的比例转换
transform.scale.y = 高的比例转换
transform.rotation
transform.rotation.x
transform.rotation.y
transform.rotation.z = 平面圆的旋转
transform.scale
transform.scale.x
transform.scale.y
transform.scale.z
transform.translation
transform.translation.x
transform.translation.y
transform.translation.z
Layer属性:
opacity = 不透明度
margin
zPosition
backgroundColor 背景颜色
cornerRadius 圆角
borderWidth
bounds
contents
contentsRect
cornerRadius
frame
hidden
mask
masksToBounds
opacity
position
shadowColor
shadowOffset
shadowOpacity
shadowRadius
- (void)caBasicAnimate { UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"test1"]]; //192 × 168 pixels imgView.frame = CGRectMake(150, 300, 192/2, 168/2); [self.view addSubview:imgView];
//1、给layer添加动画,选定角色CALayer CALayer *la = imgView.layer;
//2、写第一个剧本CAAnimation CABasicAnimation *scaleAni = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; //开始倍数 scaleAni.fromValue = [NSNumber numberWithDouble:1.0]; //结束倍数 scaleAni.toValue = [NSNumber numberWithDouble:1.2]; //自动反转 scaleAni.autoreverses = YES; // scaleAni.fillMode = kCAFillModeForwards; //重复次数,MAXFLOAT表示无限循环 scaleAni.repeatCount = MAXFLOAT; //一次动画执行时间 scaleAni.duration = 2.0;
//3、写第二个剧本用来透明 CABasicAnimation *opacityAni = [CABasicAnimation animationWithKeyPath:@"opacity"]; //完全透明 opacityAni.fromValue = [NSNumber numberWithDouble:0.0]; //完全不透明 opacityAni.toValue = [NSNumber numberWithDouble:1.0]; opacityAni.fillMode = kCAFillModeForwards; //执行时间 opacityAni.duration = 2.0; //自动反转 opacityAni.autoreverses = YES; //重复次数 opacityAni.repeatCount = MAXFLOAT;
//4、把剧本交给演员开始动画,forKey,表示给动画增加标记 [la addAnimation:scaleAni forKey:@"scaleAnimate"]; [la addAnimation:opacityAni forKey:@"opacityAnimate"]; } |
关键帧动画
CAKeyframeAnimation
//关键帧动画 - (void)keyFrameAnimate { UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"test1"]]; //192 × 168 pixels imgView.frame = CGRectMake(150, 200, 192/4, 168/4); [self.view addSubview:imgView];
//1、选定角色CALayer CALayer *layer = imgView.layer;
//2、写剧本 CAKeyframeAnimation *keyAnimate = [CAKeyframeAnimation animationWithKeyPath:@"position"]; //3、设置关键帧 NSValue *value0 = [NSValue valueWithCGPoint:layer.position]; NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(layer.position.x, layer.position.y + 200)]; NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(layer.position.x - 150, layer.position.y + 200)]; NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(layer.position.x - 150, layer.position.y)]; NSValue *value4 = [NSValue valueWithCGPoint:layer.position];
keyAnimate.values = @[value0,value1,value2,value3,value4];
//设置每个关键帧的时间曲线 CAMediaTimingFunction *ft0 = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CAMediaTimingFunction *ft1 = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
CAMediaTimingFunction *ft2 = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
CAMediaTimingFunction *ft3 = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; keyAnimate.timingFunctions = @[ft0,ft1,ft2,ft3];
//控制每段的执行时间 NSNumber *t0 = [NSNumber numberWithDouble:0.0]; NSNumber *t1 = [NSNumber numberWithDouble:0.5]; NSNumber *t2 = [NSNumber numberWithDouble:0.6]; NSNumber *t3 = [NSNumber numberWithDouble:0.7]; NSNumber *t4 = [NSNumber numberWithDouble:1]; keyAnimate.keyTimes = @[t0,t1,t2,t3,t4];
keyAnimate.autoreverses = false; keyAnimate.repeatCount = MAXFLOAT; keyAnimate.duration = 6.0;
//4、start [layer addAnimation:keyAnimate forKey:@"keyAnimate"];
} |
事务类CATransaction(导演)