iOS開(kāi)發(fā):兩行代碼實(shí)現(xiàn)動(dòng)態(tài)啟動(dòng)頁(yè)

Github:https://github.com/lxypeter/CYLaunchAnimateViewController

很多如新浪微博,閑魚(yú)等常用App在啟動(dòng)后都會(huì)有一個(gè)啟動(dòng)頁(yè)的延伸您访,作為廣告頁(yè)或介紹頁(yè)使用。仿照這種模式封裝了一個(gè)Controller驱犹,簡(jiǎn)便地實(shí)現(xiàn)這種帶動(dòng)畫(huà)的延伸頁(yè)面鸵贬。

Demo

現(xiàn)在主要提供了如下幾種動(dòng)畫(huà)效果提供使用脚线。具體可參照CYLaunchAnimateViewController.h 中的枚舉宣蠕。


CYLaunchAnimateTypeFade

CYLaunchAnimateTypeFadeAndZoomIn

CYLaunchAnimateTypePointZoomIn1
CYLaunchAnimateTypePointZoomIn2

CYLaunchAnimateTypePointZoomOut

如何使用

作為啟動(dòng)頁(yè)的延伸例隆,具體的調(diào)用應(yīng)該在 AppDelegate.m中完成。更多具體的客制化參數(shù)可到CYLaunchAnimateViewController.h中查看植影。

  1. 導(dǎo)入CYLaunchAnimateViewController.h
  #import "CYLaunchAnimateViewController.h"
  1. 初始化延伸啟動(dòng)頁(yè)View
  //just an example
  UIView *launchView = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];
  /*
  * launchView setting...
  */
  1. 初始化CYLaunchAnimateViewController裳擎,并調(diào)用show方法涎永。(在調(diào)用show方法展示前請(qǐng)確保keyWindow已經(jīng)設(shè)置)
CYLaunchAnimateViewController *launchController = [[CYLaunchAnimateViewController alloc]initWithContentView:launchView animateType:CYLaunchAnimateTypePointZoomOut showSkipButton:YES];
[launchController show];

注意contentView并不一定要是屏幕大小思币,任意大小的View都可作為延伸啟動(dòng)頁(yè)View鹿响,CYLaunchAnimateViewController會(huì)自動(dòng)將View設(shè)置到屏幕中央。


FadeWithOutBackground

實(shí)現(xiàn)思路

CYLaunchAnimateViewController應(yīng)該提供的是任意延伸頁(yè)面的展示以及消失時(shí)的動(dòng)畫(huà)效果谷饿,因而實(shí)現(xiàn)主要分為三步:

  • 1.延伸頁(yè)面的設(shè)置惶我;
  • 2.延伸頁(yè)面的展示;
  • 3.結(jié)束動(dòng)畫(huà)效果的實(shí)現(xiàn)博投;

1.延伸頁(yè)面的設(shè)置

為適配任意大小的延伸頁(yè)绸贡,在加載頁(yè)面時(shí)將控制器viewbackgroundColor設(shè)為透明色并將自定義的延伸頁(yè)作為subView設(shè)于屏幕正中。

- (void)configureSubViews{
    NSAssert(_contentView, @"contentView must not be nil!");
    self.view.backgroundColor = [UIColor clearColor];

    _contentView.center = CGPointMake(self.view.center.x, self.view.center.y);
    [self.view addSubview:_contentView];
    
    if(self.showSkipButton){
        self.skipButton.remainSec = _waitDuration;
        [self.view addSubview:self.skipButton];
        [self.skipButton addTarget:self action:@selector(dismissAtOnce) forControlEvents:UIControlEventTouchUpInside];
    }
}

2.延伸頁(yè)面的展示

作為啟動(dòng)頁(yè)的延伸毅哗,延伸頁(yè)面需要緊跟靜態(tài)啟動(dòng)頁(yè)并在在根控制器視圖上層(淡出動(dòng)畫(huà)所需)听怕。因?yàn)橐WC延伸頁(yè)置于根控制器上層,網(wǎng)上有另一種實(shí)現(xiàn)方法是將延伸頁(yè)的設(shè)置和控制的代碼置于根控制器的生命周期之中虑绵,雖然可以實(shí)現(xiàn)相同的效果尿瞭,但耦合性較強(qiáng)并不方便組件化,所以我采用了另一種方式——將延伸頁(yè)面直接添加到程序已經(jīng)初始化的keyWindow之上翅睛。

- (void)show{
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    NSAssert(window,@"keyWindow must be init!");
    [window addSubview:self.view];
}

當(dāng)頁(yè)面加載完成声搁,初始化計(jì)時(shí)器NSTimer,開(kāi)始倒計(jì)時(shí)捕发。有限的支持有小數(shù)位的等待時(shí)間疏旨,每0.1秒觸發(fā)一次- (void)countDown方法,將誤差控制在0.1秒以內(nèi)扎酷。

- (void)configureTimer{
    self.timePass = 0.0;
    NSTimer *timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(countDown) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
    self.timer = timer;
    [timer fire];
}

刷新skipButton上的倒計(jì)時(shí)(如有)檐涝,判斷倒計(jì)時(shí)是否結(jié)束。結(jié)束時(shí)停止計(jì)時(shí)器霞玄,開(kāi)始結(jié)束動(dòng)畫(huà)骤铃。

- (void)countDown{
    _timePass+=0.1;
    _skipButton.remainSec = _waitDuration-_timePass<0?0:_waitDuration-_timePass;
    if(_waitDuration<=_timePass){
        [self.timer invalidate];
        self.timer = nil;
        [self dismiss];
    }
}

3.結(jié)束動(dòng)畫(huà)效果的實(shí)現(xiàn)

結(jié)束動(dòng)畫(huà)就是CYLaunchAnimateViewController的view的消失過(guò)程。以核心動(dòng)畫(huà)和CAShapeLayer為基礎(chǔ)坷剧,CYLaunchAnimateViewController自身作為動(dòng)畫(huà)的代理惰爬,監(jiān)控動(dòng)畫(huà)的周期。以CYLaunchAnimateTypeFadeCYLaunchAnimateTypePointZoomIn1兩種動(dòng)畫(huà)效果為例惫企。

- (void)dismiss{
    
    switch (self.animateType){
        case CYLaunchAnimateTypeFade:{
            CABasicAnimation *animation = [CABasicAnimation animation];
            animation.delegate = self;
            [animation setDuration:_animateDuration];
            animation.keyPath = @"opacity";
            animation.toValue = @(0);
            [self.view.layer addAnimation:animation forKey:nil];
            break;
        }
        //...
        case CYLaunchAnimateTypePointZoomIn1:{
            CAShapeLayer *maskLayer = [CAShapeLayer layer];
            self.view.layer.mask = maskLayer;
            
            CGSize screenSize = [UIScreen mainScreen].bounds.size;
            
            CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"path"];
            [keyFrameAnimation setDuration:_animateDuration];
            keyFrameAnimation.delegate = self;
            
            UIBezierPath *pathOne = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.view.center.x, self.view.center.y) radius:hypot(screenSize.height, screenSize.width)/2 startAngle:0 endAngle:2 * M_PI clockwise:NO];
            
            UIBezierPath *pathTwo = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.view.center.x, self.view.center.y) radius:screenSize.width/2*0.5 startAngle:0 endAngle:2 * M_PI clockwise:NO];
            
            UIBezierPath *pathThree = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.view.center.x, self.view.center.y) radius:screenSize.width/2*0.7 startAngle:0 endAngle:2 * M_PI clockwise:NO];
            
            UIBezierPath *pathFour = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.view.center.x, self.view.center.y) radius:1 startAngle:0 endAngle:2 * M_PI clockwise:NO];
            
            keyFrameAnimation.values = @[(__bridge id)(pathOne.CGPath),(__bridge id)(pathTwo.CGPath),(__bridge id)(pathThree.CGPath),(__bridge id)(pathFour.CGPath)];
            keyFrameAnimation.keyTimes = @[@(0),@(0.5),@(0.9),@(1)];
            
            [maskLayer addAnimation:keyFrameAnimation forKey:nil];
            
            break;
        }
        //...
        default:
            break;
    }
}

當(dāng)動(dòng)畫(huà)結(jié)束撕瞧,CYLaunchAnimateViewController的view從keyWindow移除,執(zhí)行completeblock中內(nèi)容(如有)狞尔。

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    [self dismissAtOnce];
}

- (void)dismissAtOnce{
    [self.timer invalidate];
    self.timer = nil;
    [self.view removeFromSuperview];
    if (_complete) {
        self.complete();
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末丛版,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子偏序,更是在濱河造成了極大的恐慌页畦,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件研儒,死亡現(xiàn)場(chǎng)離奇詭異豫缨,居然都是意外死亡独令,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)好芭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)燃箭,“玉大人,你說(shuō)我怎么就攤上這事舍败≌欣辏” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵邻薯,是天一觀的道長(zhǎng)裙戏。 經(jīng)常有香客問(wèn)我,道長(zhǎng)厕诡,這世上最難降的妖魔是什么挽懦? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮木人,結(jié)果婚禮上信柿,老公的妹妹穿的比我還像新娘。我一直安慰自己醒第,他們只是感情好渔嚷,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著稠曼,像睡著了一般形病。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上霞幅,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天漠吻,我揣著相機(jī)與錄音,去河邊找鬼司恳。 笑死途乃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扔傅。 我是一名探鬼主播耍共,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼猎塞!你這毒婦竟也來(lái)了试读?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荠耽,失蹤者是張志新(化名)和其女友劉穎钩骇,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡倘屹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年韩容,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唐瀑。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖插爹,靈堂內(nèi)的尸體忽然破棺而出哄辣,到底是詐尸還是另有隱情,我是刑警寧澤赠尾,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布力穗,位于F島的核電站,受9級(jí)特大地震影響气嫁,放射性物質(zhì)發(fā)生泄漏当窗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一寸宵、第九天 我趴在偏房一處隱蔽的房頂上張望崖面。 院中可真熱鬧,春花似錦梯影、人聲如沸巫员。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)简识。三九已至,卻和暖如春感猛,著一層夾襖步出監(jiān)牢的瞬間七扰,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工陪白, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颈走,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓咱士,卻偏偏與公主長(zhǎng)得像疫鹊,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子司致,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,522評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)拆吆、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,029評(píng)論 4 62
  • 《古風(fēng)·母愛(ài)》 溫志齡 疾馳可遁形脂矫,救子寧捐生枣耀。 悲愴驚天地,英魂泣鬼神。 注:一母兩子...
    碧野牧歌閱讀 220評(píng)論 0 3
  • 一級(jí)標(biāo)題 二級(jí)標(biāo)題 三級(jí)標(biāo)題 四級(jí)標(biāo)題 五級(jí)標(biāo)題 六級(jí)標(biāo)題 文本1 文本2 文本3簡(jiǎn)書(shū)
    chi1st閱讀 243評(píng)論 0 0
  • 你知道了嗎捞奕?我是一個(gè)農(nóng)村來(lái)的菇?jīng)鑫撸皇翘赝庀颉倓偝錾鐣?huì)的我颅围,好多搞不懂的東西和事情伟葫。我很多時(shí)候又不好意思問(wèn)人,怕...
    樂(lè)樂(lè)隨心室閱讀 589評(píng)論 0 0