就2小時(shí)教會(huì)你抽絲剝繭CAAnimation核心動(dòng)畫之精美的下載動(dòng)畫

閑來無事,狂進(jìn)了materialup網(wǎng)站,不經(jīng)意間瞅見一個(gè)下載的小動(dòng)畫,覺得很是有趣.于是,我就它給實(shí)現(xiàn)一下~

設(shè)計(jì)靈感

設(shè)計(jì)此效果的作者 Nick;

images
images

開始之前你需要了解的

先上一張CAAnimation層次圖:


images
images

圖上只是一些類的常用屬性,后邊更多代碼會(huì)講到.

怎樣分解動(dòng)畫

關(guān)于分解gif,其實(shí)用mac 預(yù)覽 開發(fā)gif文件,就可以看到所有幀的圖片.


images
images

選取其中幾張動(dòng)畫節(jié)點(diǎn)的圖片存好備用.比如:


images
images

images
images

images
images

images
images

images
images

考慮到適配問題service類里已經(jīng)提取好了.

怎樣連貫動(dòng)畫

連貫動(dòng)畫是展示你做的效果流暢不流暢,看著舒服不舒服的能力.其實(shí)我是也是嘗試很多遍,讓很多人看了這個(gè)效果,有說別扭的咱就改,咋順咋來.所以讓動(dòng)畫連貫起來尤為重要.

第一,就是要?jiǎng)赢嫻?jié)點(diǎn)要選準(zhǔn)確,定位好動(dòng)畫與動(dòng)畫的銜接處.
第二,讓動(dòng)畫結(jié)束時(shí),恢復(fù)自然狀態(tài),而不是默認(rèn)狀態(tài).盡量不要有太大的差異和不規(guī)整的地方
第三,使用組合動(dòng)畫,掐好時(shí)間節(jié)點(diǎn).

簡單的就說就說這么多,下面我們開始演練代碼~~~~~~

代碼實(shí)現(xiàn)

基本實(shí)現(xiàn)想法

1.自定義UIControl類,因?yàn)樗旧砭褪荱IView子類,做點(diǎn)擊事件的View再好不過.(另一種方式用block點(diǎn)擊回調(diào))

1.使用代理,繼承UIView.

2.點(diǎn)擊區(qū)域是否在圓內(nèi)判斷

3.兩個(gè)CAShapeLayer圓環(huán)+(一個(gè)CAShapeLayer箭頭和CAShapeLayer豎線)組合成箭頭+label

4.一個(gè)service類管理創(chuàng)建所用到的path和animation

service 類

service屬性

@property (nonatomic , assign) CGRect viewRect;

@property (nonatomic, strong) UIBezierPath *progressPath;
/**    關(guān)鍵幀    **/
@property (nonatomic, strong) UIBezierPath *arrowStartPath;
@property (nonatomic, strong) UIBezierPath *arrowDownPath;
@property (nonatomic, strong) UIBezierPath *arrowMidtPath;
@property (nonatomic, strong) UIBezierPath *arrowEndPath;

@property (nonatomic, strong) UIBezierPath *arrowWavePath;

@property (nonatomic, strong) UIBezierPath *verticalLineStartPath;
@property (nonatomic, strong) UIBezierPath *verticalLineEndPath;

@property (nonatomic, strong) UIBezierPath *succesPath;

service方法

/**
 *  線到點(diǎn)動(dòng)畫
 *
 *  @param values 關(guān)鍵幀
 *
 *  @return 動(dòng)畫組
 */
- (CAAnimationGroup *)getLineToPointUpAnimationWithValues:(NSArray *)values;
/**
 *  箭頭到線的動(dòng)畫
 *
 *  @param values 關(guān)鍵幀
 *
 *  @return 動(dòng)畫組
 */
- (CAAnimationGroup *)getArrowToLineAnimationWithValues:(NSArray *)values;
/**
 *  獲取圓圈進(jìn)度
 *
 *  @param progress 當(dāng)前進(jìn)度值
 *
 *  @return path
 */
- (UIBezierPath *)getCirclePathWithProgress:(CGFloat)progress;
/**
 *  繪制波浪線
 *
 *  @param offset  偏移量
 *  @param height    浪高
 *  @param curvature 浪曲
 *
 *  @return path
 */
- (UIBezierPath *)getWavePathWithOffset:(CGFloat)offset
                             WaveHeight:(CGFloat)height
                          WaveCurvature:(CGFloat)curvature;
/**
 *  是否顯示進(jìn)度label
 *
 *  @param isShow YES/NO
 *
 *  @return 彈性動(dòng)畫
 */
- (CASpringAnimation *)getProgressAnimationShow:(BOOL)isShow;
/**
 *  線變成功動(dòng)畫
 *
 *  @param values 關(guān)鍵幀
 *
 *  @return 動(dòng)畫組
 */
- (CAAnimationGroup *)getLineToSuccessAnimationWithValues:(NSArray *)values;
/**
 *  獲取進(jìn)度label Rect
 *
 *  @return Rect
 */
- (CGRect)getProgressRect;

service key

/*  animation key  */

static NSString  * kLineToPointUpAnimationKey = @"kLineToPointUpAnimationKey";

static NSString  * kArrowToLineAnimationKey = @"kArrowToLineAnimationKey";

static NSString  * kProgressAnimationKey = @"kProgressAnimationKey";

static NSString  * kSuccessAnimationKey = @"kSuccessAnimationKey";

service 比例系數(shù)

//箭頭比例
static const double arrowHScale = 130.00/250.00;
//箭頭頭部高比例
static const double arrowTWScale = 96.00/250.00;
static const double arrowTHScale = 50.00/250.00;
//
static const double lineWScale = 176.00/250.00;
static const double pointSpacingScale = 16.00/250.00;

static const double successPoint1ScaleX = 90.00/250.00;
static const double successPoint1ScaleY = 126.00/250.00;

static const double successPoint2ScaleX = 120.00/250.00;
static const double successPoint2ScaleY = 160.00/250.00;

static const double successPoint3ScaleX = 177.00/250.00;
static const double successPoint3ScaleY = 95.00/250.00;

static const  NSInteger  kSpacing = 2;

download 類

屬性

/**
 *  進(jìn)度:0~1
 */
@property (nonatomic, assign) CGFloat progress;
/**
 *  進(jìn)度寬
 */
@property (nonatomic, assign) CGFloat progressWidth;
/**
 *  是否下載成功
 */
@property (nonatomic, assign) BOOL isSuccess;
/**
 *  委托代理
 */
@property (nonatomic, weak) id<JSDownloadAnimationDelegate> delegate;

所有方法預(yù)覽

images
images

代理

@protocol JSDownloadAnimationDelegate <NSObject>

@required
- (void)animationStart;

@optional
- (void)animationSuspend;

- (void)animationEnd;

@end

方法比較多,在這不一一展示了,有感興趣的童鞋可以直接去github下載,記得點(diǎn)個(gè)星星哦~~~??

調(diào)用

使用全真網(wǎng)絡(luò)下載

- (void)downTask{

    //1M
//    NSString*url = @"http://obh6cwxkc.bkt.clouddn.com/146621166967.jpg";
    //26M
    NSString*url = @"http://obh6cwxkc.bkt.clouddn.com/iStat%20Menus.app.zip";
    //文件比較大  200M
//    NSString*url = @"http://obh6cwxkc.bkt.clouddn.com/Command_Line_Tools_OS_X_10.11_for_Xcode_7.3.1.dmg";
    
    [self.manager downloadWithURL:url
                         progress:^(NSProgress *downloadProgress) {
                        
                             dispatch_async(dispatch_get_main_queue(), ^{
                                 NSString *progressString  = [NSString stringWithFormat:@"%.2f",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount];
                                 self.downloadView.progress = progressString.floatValue;
                             });
                             
                         }
                             path:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
                                 //
                                 NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
                                 NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
                                 return [NSURL fileURLWithPath:path];
                             }
                       completion:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
                           //此時(shí)已在主線程
                           self.downloadView.isSuccess = YES;
                           NSString *path = [filePath path];
                           NSLog(@"************文件路徑:%@",path);
                       }];
}

最終效果

現(xiàn)實(shí)與理想還是有些差距,希望不是很大,在此分享一下自己研究的經(jīng)驗(yàn),有任何問題都可以Issues我,

images
images

Release notes

Version 1.1.0

  • 使用代理委托,取消繼承uicontro,利用代理觀察事件觸發(fā)
  • 優(yōu)化動(dòng)畫,抽離波浪動(dòng)畫,單獨(dú)利用定時(shí)器動(dòng)畫.
  • 真實(shí)模擬網(wǎng)絡(luò)數(shù)據(jù)下載

Version 1.0

  • 1.0版下載動(dòng)畫

MIT License

MIT License

Copyright (c) 2016 喬同X

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末包吝,一起剝皮案震驚了整個(gè)濱河市忧风,隨后出現(xiàn)的幾起案子延刘,更是在濱河造成了極大的恐慌见坑,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绣溜,死亡現(xiàn)場離奇詭異方面,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)合冀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來项贺,“玉大人君躺,你說我怎么就攤上這事】校” “怎么了棕叫?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長奕删。 經(jīng)常有香客問我俺泣,道長,這世上最難降的妖魔是什么完残? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任伏钠,我火速辦了婚禮,結(jié)果婚禮上谨设,老公的妹妹穿的比我還像新娘贝润。我一直安慰自己,他們只是感情好铝宵,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布打掘。 她就那樣靜靜地躺著,像睡著了一般鹏秋。 火紅的嫁衣襯著肌膚如雪尊蚁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天侣夷,我揣著相機(jī)與錄音横朋,去河邊找鬼。 笑死百拓,一個(gè)胖子當(dāng)著我的面吹牛琴锭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衙传,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼决帖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蓖捶?” 一聲冷哼從身側(cè)響起地回,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后刻像,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畅买,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年细睡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谷羞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡溜徙,死狀恐怖洒宝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情萌京,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布宏浩,位于F島的核電站知残,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏比庄。R本人自食惡果不足惜求妹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望佳窑。 院中可真熱鬧制恍,春花似錦、人聲如沸神凑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溉委。三九已至鹃唯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓣喊,已是汗流浹背坡慌。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留藻三,地道東北人洪橘。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像棵帽,于是被迫代替她去往敵國和親熄求。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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