小白學(xué)習(xí)ios動(dòng)畫(huà)效果
引言
最近公司的設(shè)計(jì)師很有空,時(shí)不時(shí)就來(lái)問(wèn)一下某些動(dòng)畫(huà)效果好不好實(shí)現(xiàn), 就學(xué)習(xí)了一下ios的動(dòng)畫(huà)實(shí)現(xiàn)方法。
發(fā)現(xiàn)其實(shí)很多漂亮的動(dòng)畫(huà)效果都是幾種基礎(chǔ)的動(dòng)畫(huà)效果組合而成,總結(jié)一下基本的動(dòng)畫(huà)實(shí)現(xiàn)方法。并做了一個(gè)UIView擴(kuò)展類。共同對(duì)抗設(shè)計(jì)師
地址:[https://github.com/mozhenhau/D3View]
一、動(dòng)畫(huà)方式
UIView動(dòng)畫(huà)(Core Animation)
CALayer繪畫(huà) (Core Graphics)
二、UIView動(dòng)畫(huà) animateWithDuration
我只用block=。=
參數(shù)說(shuō)明
'' [UIView animateWithDuration:1 delay:0.5 options:UIViewAnimationOptionCurveEaseOut animations:^{
'' //要進(jìn)行的動(dòng)畫(huà)區(qū)
'' _testView.alpha = 0;
'' } completion:^(BOOL finished) {
'' //動(dòng)畫(huà)完成后操作
'' }];
需要參數(shù):
duration: 動(dòng)畫(huà)時(shí)長(zhǎng)
delay: 決定了動(dòng)畫(huà)在延遲多久之后執(zhí)行
options:用來(lái)決定動(dòng)畫(huà)的展示方式,接下來(lái)會(huì)進(jìn)行講解
animations:轉(zhuǎn)化成動(dòng)畫(huà)表示的代碼
completion:動(dòng)畫(huà)結(jié)束后執(zhí)行的代碼塊
動(dòng)畫(huà)區(qū)有效的屬性animations:
坐標(biāo)尺寸(bounds,frame,center)、
視圖顯示(backgroundColor,alpha,hidden)
形態(tài)變化 (transform)
動(dòng)畫(huà)展示方式options:
看一下官方文檔的展示方式有哪些:我看不懂的只能原文貼上了= 。 =
-
常規(guī)屬性
'' enum {
'' //默認(rèn),跟父類作為一個(gè)整體
'' UIViewAnimationOptionLayoutSubviews = 1 << 0,
'' //設(shè)置了這個(gè),主線程可以接收點(diǎn)擊事件
'' UIViewAnimationOptionAllowUserInteraction = 1 << 1,
'' //從當(dāng)前狀態(tài)開(kāi)始動(dòng)畫(huà),父層動(dòng)畫(huà)運(yùn)動(dòng)期間,開(kāi)始子層動(dòng)畫(huà)。
'' UIViewAnimationOptionBeginFromCurrentState = 1 << 2,
'' //重復(fù)執(zhí)行動(dòng)畫(huà),從開(kāi)始到結(jié)束, 結(jié)束后直接跳到開(kāi)始態(tài)
'' UIViewAnimationOptionRepeat = 1 << 3,
'' //反向執(zhí)行動(dòng)畫(huà),結(jié)束后會(huì)再?gòu)慕Y(jié)束態(tài)->開(kāi)始態(tài)
'' UIViewAnimationOptionAutoreverse = 1 << 4,
'' //忽略繼承自父層持續(xù)時(shí)間,使用自己持續(xù)時(shí)間(如果存在)
'' UIViewAnimationOptionOverrideInheritedDuration = 1 << 5,
'' //忽略繼承自父層的線性效果,使用自己的線性效果(如果存在)
'' UIViewAnimationOptionOverrideInheritedCurve = 1 << 6,
'' //允許同一個(gè)view的多個(gè)動(dòng)畫(huà)同時(shí)進(jìn)行
'' UIViewAnimationOptionAllowAnimatedContent = 1 << 7,
'' UIViewAnimationOptionShowHideTransitionViews = 1 << 8,
'' UIViewAnimationOptionOverrideInheritedOptions = 1 << 9,
''
-
Curve速度變化方式
'' //開(kāi)始慢,加速到中間,然后減慢到結(jié)束
'' UIViewAnimationOptionCurveEaseInOut = 0 << 16,
'' //開(kāi)始慢,加速到結(jié)束
'' UIViewAnimationOptionCurveEaseIn = 1 << 16,
'' //開(kāi)始快,減速到結(jié)束
'' UIViewAnimationOptionCurveEaseOut = 2 << 16,
'' //線性運(yùn)動(dòng)
'' UIViewAnimationOptionCurveLinear = 3 << 16,
''
-
transitionWithView,轉(zhuǎn)場(chǎng)方式
'' UIViewAnimationOptionTransitionNone = 0 << 20,
'' //從左往右翻頁(yè)
'' UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20,
'' //從右往左翻頁(yè)
'' UIViewAnimationOptionTransitionFlipFromRight = 2 << 20,
'' //從下往上卷曲翻頁(yè)
'' UIViewAnimationOptionTransitionCurlUp = 3 << 20,
'' //從上往下卷曲翻頁(yè)
'' UIViewAnimationOptionTransitionCurlDown = 4 << 20,
'' ////轉(zhuǎn)場(chǎng)交叉消失,漸隱漸現(xiàn)
'' UIViewAnimationOptionTransitionCrossDissolve = 5 << 20,
'' //從上往下翻頁(yè)
'' UIViewAnimationOptionTransitionFlipFromTop = 6 << 20,
'' //從下往上翻頁(yè)
'' UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20,
'' };
'' typedef NSUInteger UIViewAnimationOptions;
重點(diǎn)提一下這幾個(gè)值,接下來(lái)使用下面的值做一下常用動(dòng)畫(huà)
UIViewAnimationOptionRepeat (從開(kāi)始態(tài)到結(jié)束態(tài)重復(fù)執(zhí)行)
UIViewAnimationOptionAutoreverse (結(jié)束后會(huì)反向再執(zhí)行一次)
UIViewAnimationOptionCurveEaseInOut (慢開(kāi)始加速->到中間后開(kāi)始減速)
UIViewAnimationOptionCurveEaseIn (開(kāi)始慢,加速到結(jié)束 )
UIViewAnimationOptionCurveEaseOut (開(kāi)始快,減速到結(jié)束)
UIViewAnimationOptionCurveLinear (線性速度)
例子
-
這里通過(guò)這些屬性實(shí)現(xiàn)一個(gè)上下來(lái)回的動(dòng)畫(huà): =。=
'' [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationCurveEaseOut animations:^{
'' _testView.frame = CGRectMake(135, -100, 50, 200);
'' } completion:nil];
效果:
此處輸入圖片的描述
-
旋轉(zhuǎn)動(dòng)畫(huà):
'' [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionRepeat |UIViewAnimationOptionCurveLinear animations:^{
'' _testView.transform = CGAffineTransformMakeRotation(M_PI);
'' } completion:nil];
效果:

-
上下來(lái)回和旋轉(zhuǎn)動(dòng)畫(huà)一起:
'' [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationCurveEaseOut animations:^{
'' _testView.frame = CGRectMake(135, 200, 50, 50);
''
'' [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionRepeat |UIViewAnimationOptionCurveLinear animations:^{
'' _testView.transform = CGAffineTransformMakeRotation(M_PI);
'' } completion:nil];
''
'' } completion:nil];
效果:

復(fù)雜的動(dòng)畫(huà)效果都是通過(guò)集中簡(jiǎn)單的動(dòng)畫(huà)組合而成,可以嘗試分解動(dòng)畫(huà),然后一個(gè)個(gè)組合。
使用Spring Animation API (彈性動(dòng)畫(huà))
Spring Animation 的 API 和一般動(dòng)畫(huà)相比多了兩個(gè)參數(shù),分別是usingSpringWithDamping和initialSpringVelocity。
- usingSpringWithDamping參數(shù)
usingSpringWithDamping的范圍為0.0f到1.0f,數(shù)值越小「彈簧」的振動(dòng)效果越明顯. 下面引用別人家的圖片

- initialSpringVelocity 參數(shù)
initialSpringVelocity則表示初始的速度,數(shù)值越大一開(kāi)始移動(dòng)越快。

使用Spring Animation能更好地實(shí)現(xiàn)自定義的動(dòng)畫(huà)效果,能自己定義開(kāi)始速度,能方便地使用常用的彈性動(dòng)畫(huà)。
三、CALayer 通過(guò)繪圖的方式實(shí)現(xiàn)自定義動(dòng)畫(huà)
Core Graphics Framework是一套基于C的API框架,使用了Quartz作為繪圖引擎。它提供了低級(jí)別、輕量級(jí)、高保真度的2D渲染。該框架可以用于基于路徑的繪圖、變換、顏色管理、脫屏渲染,模板、漸變、遮蔽、圖像數(shù)據(jù)管理、圖像的創(chuàng)建、遮罩以及PDF文檔的創(chuàng)建、顯示和分析。
iOS支持兩套圖形API族:Core Graphics/QuartZ 2D 和OpenGL ES。OpenGL ES是跨平臺(tái)的圖形API,屬于OpenGL的一個(gè)簡(jiǎn)化版本。QuartZ 2D是蘋(píng)果公司開(kāi)發(fā)的一套API,它是Core Graphics Framework的一部分。
繪圖步驟:
獲取上下文
創(chuàng)建路徑并設(shè)置路徑
將屬性添加到上下文
設(shè)置上下文屬性
繪制路徑
釋放路徑
使用方法:
新建一個(gè)文件,繼承UIView
重寫(xiě)-(void)drawRect:(CGRect)rect方法
在drawRect方法內(nèi)執(zhí)行上面的繪圖步驟
CALayer各種繪圖
1.畫(huà)直線
''
'' -(void)drawRect:(CGRect)rect{
'' [self drawLine];
'' }
''
'' //畫(huà)直線
'' -(void)drawLine{
'' CGContextRef ctx = UIGraphicsGetCurrentContext();
'' // CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor); //填充的顏色
'' // CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor); //描邊的顏色
'' // CGContextSetLineWidth(ctx, 5); //描邊的寬度
''
'' //畫(huà)線方法1,使用CGContextAddLineToPoint畫(huà)線,需要先設(shè)置一個(gè)起始點(diǎn)
'' //設(shè)置起始點(diǎn)
'' CGContextMoveToPoint(ctx, 50, 50);
'' //添加一個(gè)點(diǎn)
'' CGContextAddLineToPoint(ctx, 100,50);
''
'' //畫(huà)線方法2
'' //利用路徑去畫(huà)一組點(diǎn)
'' // CGMutablePathRef path = CGPathCreateMutable();
'' // CGPathMoveToPoint(path, nil, 0, 200);
'' // CGPathAddLineToPoint(path, nil, 100, 250);
'' // CGContextAddPath(ctx, path);
''
'' // CGContextFillPath(ctx); //填充
'' // CGPathRelease(path);
'' CGContextStrokePath(ctx); //描邊
'' }
2.畫(huà)圓
'' //畫(huà)圓
'' -(void)drawRound{
'' CGContextRef ctx = UIGraphicsGetCurrentContext();
'' CGContextMoveToPoint(ctx, 100, 100);//移動(dòng)畫(huà)筆到指定坐標(biāo)點(diǎn)
'' CGContextAddArc (ctx, 100, 100, 50, 0, 2*M_PI , 0);
''
'' //畫(huà)橢圓,如果長(zhǎng)寬相等就是圓
'' // CGContextAddEllipseInRect(ctx, CGRectMake(0, 250, 50, 50));
'' CGContextFillPath(ctx);
'' }
3.畫(huà)矩形
'' //畫(huà)矩形
'' -(void)drawRect{
'' CGContextRef ctx = UIGraphicsGetCurrentContext();
'' CGContextAddRect(ctx, CGRectMake(0, 250, 50, 50));
'' CGContextFillPath(ctx);
'' }
4.畫(huà)多邊形
'' //畫(huà)多邊形
'' -(void)drawPolygen{
'' CGContextRef ctx = UIGraphicsGetCurrentContext();
''
'' CGMutablePathRef path = CGPathCreateMutable();
'' CGPathMoveToPoint(path, nil, 120, 250);
'' CGPathAddLineToPoint(path, nil, 200, 250);
'' CGPathAddLineToPoint(path, nil, 180, 300);
'' CGPathCloseSubpath(path); //關(guān)鍵點(diǎn),封閉路徑,首尾連接
'' CGContextAddPath(ctx, path);
'' CGContextFillPath(ctx);
'' }
5.畫(huà)圖片
'' //畫(huà)圖片
'' -(void)drawImage{
'' // CGContextRef ctx = UIGraphicsGetCurrentContext();
'' UIImage *image = [UIImage imageNamed:@"test"];
'' [image drawInRect:CGRectMake(0, 0, 100, 100)];
'' }
6.畫(huà)文字
'' //畫(huà)文字
'' -(void)drawText{
'' //文字樣式
'' UIFont *font = [UIFont systemFontOfSize:18];
'' NSDictionary *dict = @{NSFontAttributeName:font,
'' NSForegroundColorAttributeName:[UIColor blueColor]};
'' [@"hello world" drawInRect:CGRectMake(120 , 350, 500, 50) withAttributes:dict];
'' }
7.畫(huà)扇形
'' //畫(huà)扇形
'' -(void)drawArc{
'' CGContextRef ctx = UIGraphicsGetCurrentContext();
'' CGContextMoveToPoint(ctx, 100, 100);//移動(dòng)畫(huà)筆到指定坐標(biāo)點(diǎn)
'' CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);//填充顏色
'' CGContextAddArc(ctx, 100, 100, 50, 1.5*M_PI, 0, 0); //添加一個(gè)圓,設(shè)置角度. 最后一個(gè)值0為順時(shí)針,1為逆時(shí)針
'' CGContextFillPath(ctx);
'' }
總結(jié)
=.=要做什么高度定制動(dòng)畫(huà)可以自己繪制去, 復(fù)雜動(dòng)畫(huà)逐步分解。
實(shí)在沒(méi)想法, 出大招,甩鍋?zhàn)孶I做gif或者svg。