iOS 動畫的實(shí)現(xiàn)

為了達(dá)到好的用戶體驗(yàn)贞远,讓用戶在使用 App 交互的時(shí)候或者等待的時(shí)候視覺上有所沖擊,達(dá)到好的用戶體驗(yàn)笨忌,許多 App 都使用了各式各樣的動畫蓝仲,動畫的實(shí)現(xiàn)也無疑是開發(fā)者所必備的技能之一。

實(shí)現(xiàn) iOS 中動畫我們要了解三個(gè)類官疲,分別是CABasicAnimation袱结、UIBezierPathCAShapeLayer。簡單說一下它們各自的功能途凫,或許我們都知道垢夹,在 UI 界面層中有一個(gè) layer 的層級,這個(gè) layer 展示的是我們界面上的各個(gè)所需要繪制的畫面维费,而我們的 UIView 實(shí)際上就是對 Layer 層的一個(gè)封裝果元,在圖形的展示基礎(chǔ)上增加了交互事件處理。而所有對畫面的操作實(shí)際都是來自 Layer 層犀盟,我們可以設(shè)置圓角(cornerradius)而晒、邊框(borderWidth) 等常用的屬性。所以動畫的繪畫過程實(shí)際上就是展示變換圖形的過程阅畴,這就自然而然的引出了相應(yīng)的 Layer 層倡怎。 CAShapeLayer 繼承自 CALayer,通過 CAShapeLayer 我們可以繪制自己想要的圖形贱枣,而 UIBezierPath 就是我們經(jīng)常說的貝塞爾曲線监署,通過設(shè)置相應(yīng)的參數(shù),我們可以繪制出各式各樣的圖形來纽哥。

說了那么多钠乏,其實(shí) CAShapeLayer 就是一個(gè)畫筆,而 UIBezierPath 實(shí)際上就是要畫筆所要畫的路徑春塌,通過路徑將圖形繪制出來晓避,而 CABasicAnimation 是來控制繪畫速度以及過程。他們?nèi)呔o密相關(guān)摔笤,不可分割够滑。為了便于理解,就以進(jìn)度條的案例來進(jìn)行說明吧吕世!

/**
 *  創(chuàng)建 shapLayer
 *  
 *  @return layer 實(shí)例
 */
- (CAShapeLayer *)creatCycleView{
    
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    
    //storkeWidth 的寬度的中點(diǎn)位于半徑的軌跡上彰触,繪制的時(shí)候由軌跡路線內(nèi)外擴(kuò)展繪制,
    //所以真是繪制長度為真實(shí)長度減去軌跡長度的一半
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2.0, self.frame.size.height/2.0) radius:_radius ? _radius - _cycleWidth * 0.5 : _radius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
    
    layer.lineWidth = _cycleWidth ? _cycleWidth : DEFAULT_STORKE_WIDTH;
    layer.path = [path CGPath];

    
    return layer;
}
/**
 *  創(chuàng)建圓環(huán)背景
 */
- (void)creatView{
    
    //背景色
    self.backgroundColor = [UIColor blackColor];
    self.layer.cornerRadius = 6;
    
    CAShapeLayer *backLayer = [self creatCycleView];
    backLayer.strokeColor = _progressColor ? [_progressColor CGColor] : [[UIColor colorWithRed:59/255.0 green:59/255.0 blue:59/255.0 alpha:1]CGColor];
    backLayer.fillColor = _progressBgColor ? [_progressBgColor CGColor] : [[UIColor clearColor]CGColor];
    
    backShapeLayer = backLayer;
    
    [self.layer addSublayer:backLayer];
    
    CAShapeLayer *foreLayer = [self creatCycleView];
    foreLayer.strokeColor = _progressColor ? [_progressColor CGColor] : [[UIColor whiteColor]CGColor];
    foreLayer.fillColor = [[UIColor clearColor]CGColor];
    foreLayer.strokeStart = 0;
    foreLayer.strokeEnd = 0.3;
    foreLayer.cornerRadius = 2;
    
    //繪制線條的風(fēng)格
    if (self.cycleWidth != self.radius) {
     
        foreLayer.lineCap = kCALineCapRound;
    }
    
    
    foreShapeLayer = foreLayer;
    [self.layer addSublayer:foreLayer];
    
    
}

通過 setter 方法設(shè)置進(jìn)度條的進(jìn)度:

- (void)setProgressValue:(float)progressValue{

    _progressValue = progressValue;
    
    foreShapeLayer.strokeEnd = progressValue;
    
    //加載完成以后的回調(diào)
    if (self.loadSuccessBlock && progressValue == 1) {
        self.loadSuccessBlock(self);
    }

}

而為了讓繪制的過程更為清晰命辖,我們設(shè)置了進(jìn)度條的動畫况毅,代碼如下:


/*
*添加動畫
*/
- (void)drawCycle{

    //創(chuàng)建動畫實(shí)例
    CABasicAnimation *drawCycleAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    drawCycleAnimation.duration = DRAW_AIMATION_TIME;
    drawCycleAnimation.repeatCount = 1;
    drawCycleAnimation.delegate = self;
    
    //設(shè)置動畫內(nèi)容的起始值與結(jié)束值
    drawCycleAnimation.fromValue = [NSNumber numberWithFloat:0.3];
    drawCycleAnimation.toValue = [NSNumber numberWithFloat:1.0];
    
    //動畫時(shí)間速度
    drawCycleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    [foreShapeLayer addAnimation:drawCycleAnimation forKey:@"drawCircleAnimation"];
    
    //創(chuàng)建縮放動畫
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    basicAnimation.duration = DRAW_AIMATION_TIME;
    basicAnimation.repeatCount = 1;
    basicAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

    CATransform3D startTransForm = CATransform3DMakeScale(0, 0, 1);
    CATransform3D endTransForm = CATransform3DMakeRotation(0, 0, 0, 1);
    
    basicAnimation.fromValue = [NSValue valueWithCATransform3D:startTransForm];
    basicAnimation.toValue = [NSValue valueWithCATransform3D:endTransForm];
    
    [foreShapeLayer addAnimation:basicAnimation forKey:@"startTransform"];
    
    
}

最終的效果如下:

進(jìn)度條實(shí)例.gif

怎么樣分蓖,是不是很有意思呢?感興趣的童鞋具體 demo 詳見 Git:
https://github.com/lccdl/LCCRepository/tree/master/LCProgressDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尔许,一起剝皮案震驚了整個(gè)濱河市么鹤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌味廊,老刑警劉巖蒸甜,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異余佛,居然都是意外死亡柠新,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門辉巡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恨憎,“玉大人,你說我怎么就攤上這事郊楣°究遥” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵净蚤,是天一觀的道長钥组。 經(jīng)常有香客問我,道長塞栅,這世上最難降的妖魔是什么者铜? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任腔丧,我火速辦了婚禮放椰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘愉粤。我一直安慰自己砾医,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布衣厘。 她就那樣靜靜地躺著如蚜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪影暴。 梳的紋絲不亂的頭發(fā)上错邦,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機(jī)與錄音型宙,去河邊找鬼撬呢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛妆兑,可吹牛的內(nèi)容都是我干的魂拦。 我是一名探鬼主播毛仪,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼芯勘!你這毒婦竟也來了箱靴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤荷愕,失蹤者是張志新(化名)和其女友劉穎衡怀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體安疗,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狈癞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茂契。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝶桶。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖掉冶,靈堂內(nèi)的尸體忽然破棺而出真竖,到底是詐尸還是另有隱情,我是刑警寧澤厌小,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布恢共,位于F島的核電站,受9級特大地震影響璧亚,放射性物質(zhì)發(fā)生泄漏讨韭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一癣蟋、第九天 我趴在偏房一處隱蔽的房頂上張望透硝。 院中可真熱鬧,春花似錦疯搅、人聲如沸濒生。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罪治。三九已至,卻和暖如春礁蔗,著一層夾襖步出監(jiān)牢的瞬間觉义,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工浴井, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晒骇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像厉碟,于是被迫代替她去往敵國和親喊巍。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容