iOS动画编程
iOS动画编程
hejunbinlan 发表于3年前
iOS动画编程
  • 发表于 3年前
  • 阅读 160
  • 收藏 4
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

摘要: iOS动画编程

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;

    

    //4start

    [layer addAnimation:keyAnimate forKey:@"keyAnimate"];

    

}




事务类CATransaction(导演



共有 人打赏支持
粉丝 37
博文 529
码字总数 21018
×
hejunbinlan
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: