文档章节

iOS动画编程

hejunbinlan
 hejunbinlan
发布于 2015/06/20 23:05
字数 1479
阅读 196
收藏 4

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(导演



© 著作权归作者所有

共有 人打赏支持
hejunbinlan
粉丝 41
博文 595
码字总数 21569
作品 0
浦东
高级程序员
私信 提问
如何判断你是合格的高级iOS开发工程师?

前言 随着移动互联网的高速发展泄洪而来,有意学习移动开发的人越来越多了,竞争也是越来越大,需要学习的东西很多。如何才能在激烈的移动开发者竞争中一枝独秀,成为一名真正合格的高级iOS...

_小迷糊
05/26
0
0
ios lua 学习软件

Lua 是很容易移植到ios上的脚本语言。很多软件都实现了把lua移植到ios上,有一个软件叫“lua5.1.4-编程语言” https://itunes.apple.com/cn/app/ios-lua5.1.4/id576214731?mt=8 。它有强大...

good-good
2013/08/25
720
1
iOS 11.2 首个测试版发布,修复计算器运算错误 Bug

苹果今天向开发者发布了 iOS 11.2 第一个测试版。iOS 11.2 修复了计算器应用在快速输入时,会导致运算结果出错的 Bug。计算器 Bug 在 iOS 11 测试阶段就存在,直到 iOS 11.2 发布前,一直没有...

达尔文
2017/10/31
1K
6
好坏美丑,开发者眼中的 iOS 7

跟着新 iPhone 发布的节奏,iOS 史上转变最大的 iOS 7 将要在苹果的各类新产品上大展拳脚了。从消费者眼里看来,这种转变是拟物化向扁平化的转变和新加入的控制中心等。但是对于开发者而言,...

oschina
2013/08/29
5.3K
42
现代传播集团招募iOS高级工程师

现代传播集团招募 高级iOS开发工程师 工作地点:北京 三里屯 薪水:10k-20k 简历请发到 linyize@modernmedia.com.cn 岗位职责: 1. 负责现代传播集团 iphone/ipad 客户端应用软件开发与维护;...

linyize
2013/05/07
305
0

没有更多内容

加载失败,请刷新页面

加载更多

java框架学习日志-7(静态代理和JDK代理)

静态代理 我们平时去餐厅吃饭,不是直接告诉厨师做什么菜的,而是先告诉服务员点什么菜,然后由服务员传到给厨师,相当于服务员是厨师的代理,我们通过代理让厨师炒菜,这就是代理模式。代理...

白话
今天
13
0
Flink Window

1.Flink窗口 Window Assigner分配器。 窗口可以是时间驱动的(Time Window,例如:每30秒钟),也可以是数据驱动的(Count Window,例如:每一百个元素)。 一种经典的窗口分类可以分成: 翻...

满小茂
今天
5
0
my.ini

1

architect刘源源
今天
9
0
docker dns

There is a opensource application that solves this issue, it's called DNS Proxy Server It's a DNS server that solves containers hostnames, if could not found a hostname that mat......

kut
今天
8
0
寻找数学的广度——《这才是数学》读书笔记2700字

寻找数学的广度——《这才是数学》读书笔记2700字: 文|程哲。数学学习方式之广:国内外数学教育方面的专家,进行了很多种不同的数学学习方式尝试,如数学绘本、数学游戏、数学实验、数学步道...

原创小博客
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部