【大娃一點(diǎn)技術(shù)】iOS獲取開機(jī)畫面(啟動(dòng)圖)【9.21更新】

921更新宣言

感謝大家回來聽我道個(gè)歉堰乔。Sooooorryyyyy~~~仓犬,更好的解決方案來晚了。

最近抽空繼續(xù)研究了下超棺,又和中國(guó)好同事們一起商討(在西貝門口圍著13寸電腦邊排隊(duì)邊討論向族,此情此景)。終于有了一些新的發(fā)現(xiàn)棠绘。

之前B哥哥(我)說件相,storyboard的開機(jī)圖,我只能通過截圖的方式拿到view氧苍。這句話即對(duì)又錯(cuò)夜矗,的確如果是拿view,那么目前是只有截圖的方式让虐,但是原因并不只是約束紊撕,具體的后面說。然后換種思路赡突,如果我們拿controller对扶,會(huì)更加的方便。

接下來我會(huì)更新本篇文檔麸俘,增加補(bǔ)充controller的相關(guān)處理辩稽。根據(jù)實(shí)踐惧笛,就展示開屏从媚,我覺得(controller + new window) is more 簡(jiǎn)單 than (keywindow add view)

bBbBbBbBbBbBbBbBbBbB 華麗麗的分割線患整,以下正文 BbBbBbBbBbBbBbBbBbBb

前言的前言

作者 ==> 我 ==> 大娃 ==> Big Baby ==> BB ==> BB ==> B

以后文中出現(xiàn)B拜效,大家不要驚訝喷众,請(qǐng)保持冷靜。


前言

所謂的開機(jī)畫面紧憾,就是應(yīng)用啟動(dòng)圖到千。打開應(yīng)用的第一福畫面,這個(gè)畫面不是通過代碼寫的赴穗,而是工程配置憔四。那么我們是否有辦法通過代碼獲取到,并且呈現(xiàn)出來呢般眉?這里B給你YES了赵。

發(fā)展至今有2種方式實(shí)現(xiàn):Launch Image Source、Launch Screen File甸赃。如下圖:

其實(shí)柿汛,B一直理解為 3 種,Launch Screen File可以是xib和storyboard埠对。

基本上每個(gè)APP都會(huì)用到開機(jī)畫面络断。如果你還沒有使用,看完本文就可以和產(chǎn)品同學(xué)一起規(guī)劃了项玛。開機(jī)后貌笨,如果需要平滑延長(zhǎng)開機(jī)畫面,然后做點(diǎn)什么襟沮,就需要使用到躁绸。

如果是要實(shí)現(xiàn)開機(jī)后再顯示一會(huì)開機(jī)圖(主要是為了將這個(gè)圖片作為背景,來顯示廣告臣嚣,啊~~~~~還說出了自己的目的)净刮,大家可能會(huì)想到一些簡(jiǎn)單的解決方案:

  1. 【基礎(chǔ)方案】除了APP配置使用到的Launch Image Source或者Launch Screen File,多存一份launch image硅则,在代碼中引用到這張圖片淹父,創(chuàng)建view≡醭妫【毒舌】看似簡(jiǎn)單暑认,不過問題來了,如何解決多屏幕比例問題大审?
  2. 【加強(qiáng)版】存多個(gè)尺寸的圖片蘸际,在不同的設(shè)備,使用不同的徒扶×竿【毒舌】可以,沒毛病,和設(shè)計(jì)師配合好导坟,切圖就是了屿良。
  3. 【加強(qiáng)版EX】一般開機(jī)圖都是元素相同,布局不同惫周。代碼中我也使用動(dòng)態(tài)布局尘惧,獲取image,手動(dòng)布局递递,嘔了喷橙。【毒舌】也是思路登舞。
  4. 【加強(qiáng)版EX PRO】……

方法有很多重慢,都能解決問題,不過有個(gè)共通的問題逊躁,一旦開機(jī)圖更新似踱,復(fù)工量不小。接下來B介紹下目前自己的方法稽煤。

B介紹的方式核芽,適用iPad、iPhone及其橫酵熙、豎屏情況下轧简。如果有不適配的,請(qǐng)及時(shí)聯(lián)系我匾二,謝謝哮独。


一、思路

開機(jī)圖至少有3種方式設(shè)置察藐,我們需要通過代碼的方式獲取到這些資源皮璧。

期初我想獲取到啟動(dòng)圖的UIView,然后在keywindow上add分飞。的確這種方式挺好悴务,也方便。不過目前看來獲取UIView會(huì)有一些麻煩譬猫,而且如果APP的window一直變化讯檐,那么會(huì)造成更多意料之外的事情。所以B現(xiàn)在更傾向獲取controller染服,然后創(chuàng)建一個(gè)新的window别洪。

接下來分別介紹下如何有效獲取各種資源。

二柳刮、獲取Launch Image Source

此處先獲取開機(jī)圖的View(畢竟image的直接獲取就是view)挖垛,我們?cè)诤竺娼M建controller痒钝。

+ (NSString *)launchImageName {
    NSString *viewOrientation = UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ? @"Portrait" : @"Landscape";
    CGSize viewSize = [UIScreen mainScreen].bounds.size;

    NSString *launchImage = nil;
    NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
    for (NSDictionary* dict in imagesDict) {
        CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
        if ([self size1:imageSize equleToSize2:viewSize] &&
            [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]]) {
            launchImage = dict[@"UILaunchImageName"];
        }
    }

    return launchImage;
}

+ (UIView *)picLaunchView {
    UIView *launchView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[self launchImageName]]];
    launchView.frame = [UIScreen mainScreen].bounds;
    launchView.contentMode = UIViewContentModeScaleAspectFill;
    return launchView;
}

其中有個(gè)size比較的方法,因?yàn)榭紤]到了屏幕旋轉(zhuǎn)晕换,所以寫了個(gè)模糊判斷午乓。寫的比較隨意站宗,大家隨便看看即可闸准,這里的吐槽B就不管了。

+ (BOOL)size1:(CGSize)size1 equleToSize2:(CGSize)size2 {
    CGSize _size1;
    CGSize _size2;
    _size1.width = MIN(size1.width, size1.height);
    _size1.height = MAX(size1.width, size1.height);
    _size2.width = MIN(size2.width, size2.height);
    _size2.height = MAX(size2.width, size2.height);

    return CGSizeEqualToSize(_size1, _size2);
}

要點(diǎn)

  • 通過UILaunchImages獲取到圖片的名字梢灭;
  • 根據(jù)size比較夷家,拿到適合本設(shè)備的圖片;
  • 判斷圖片的方向敏释,拿到正確的圖片库快。這里估計(jì)有同學(xué)會(huì)問為什么要判斷方向,因?yàn)?em>B做過一個(gè)應(yīng)用同時(shí)適配豎屏iPhone和橫屏iPad钥顽。(>_<)

三义屏、獲取Launch Screen File(xib)

此處有更新,直接獲取controller蜂大。

+ (UIViewController *)nibLaunchView {
    UIView *launchView = nil;
    NSString *xibName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UILaunchStoryboardName"];
    if ([xibName length] > 0) {
        @try {
            launchView = [[[NSBundle mainBundle] loadNibNamed: xibName owner:nil options:nil] firstObject];
        } @catch (NSException *exception) {            
        }
    }

    [launchView setFrame:[UIScreen mainScreen].bounds];
    UIViewController *controller = [UIViewController new];
    [controller.view addSubview:view];
    return controller;
}

要點(diǎn)

  • 通過UILaunchStoryboardName獲取到nib的名字闽铐。沒錯(cuò),雖然是xib奶浦,但是因?yàn)槎际?code>Launch Screen File兄墅;
  • 通過name,獲取到view array澳叉。B偷懶隙咸,在這里直接使用了firstObject,作為嚴(yán)謹(jǐn)?shù)娜顺上矗鋵?shí)是可以判斷下的五督;
  • 這里的try大家也要加上。雖然你拿到了名字瓶殃,但是不一定可以拿到nib概荷。如果拿不到,loadNibNamed會(huì)拋異常的碌燕,在沒有try的情況下误证,就直接再見了。
  • setFrame是一個(gè)必要過程修壕,如果不加愈捅,你可以試試看哦。

四慈鸠、獲取Launch Screen File(storyboard)

執(zhí)意獲取UIView蓝谨,把事情變的復(fù)雜許多。直接獲取Controller,簡(jiǎn)單譬巫、有效咖楣。

+ (UIViewController *)nibLaunchView { __FunctionPoint__
    UIViewController *controller = nil;
    NSString *storyboardName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UILaunchStoryboardName"];
    if ([storyboardName length] > 0) {
        @try {
            UIStoryboard *storyboard = [UIStoryboard storyboardWithName:name bundle:nil];
            controller = [storyboard instantiateInitialViewController];
        } @catch (NSException *exception) {
        }
    }

    return controller;
}

說明

刪除了之前的解釋,B來說說之前所謂的約束當(dāng)?shù)缆簦瑂toryboard就無效的原因诱贿。

其實(shí)這么理解是不對(duì)的。當(dāng)我們獲取到storyboard.controller.view時(shí)咕缎,大部分約束是有效的珠十,那么無效的是什么——Top Layout Guide。就是它凭豪,在拿到view的時(shí)候焙蹭,這個(gè)約束是無效的。各種姿勢(shì)都試了嫂伞,始終無法獲取有效的view孔厉,除非截圖。

題外話帖努,可以忽略這段撰豺。為什么B一開始沒發(fā)現(xiàn)問題根源。說來慚愧然磷,B做頁面的經(jīng)驗(yàn)一般郑趁,特別是IB方式,還好有龍哥和山哥幫忙姿搜,讓我瞬間領(lǐng)悟寡润。懷念自己曾經(jīng)的iOS團(tuán)隊(duì):無所不知的龍哥、最穩(wěn)的特種兵強(qiáng)哥舅柜、務(wù)實(shí)的偉哥梭纹、無所不會(huì)的山哥。現(xiàn)在想想致份,都能笑出聲來变抽。匆匆2年多,感謝你們陪我一起玩氮块。分開不重要……說多了绍载。

好了,現(xiàn)在看來滔蝉,storyboard的情況下獲取controller击儡,尤為的簡(jiǎn)單。同樣是通過UILaunchStoryboardName獲取到storyboard文件蝠引。并且通過instantiateInitialViewController拿到controller阳谍。

既然xib和storyboard是類似的蛀柴,那么代碼可以整合下,一次性獲取有效內(nèi)容矫夯。

+ (UIViewController *)nibLaunchViewController {
    UIViewController *launchViewController = nil;
    NSString *storyboardName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UILaunchStoryboardName"];
    if ([storyboardName length] > 0) {
        @try {
            UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
            launchViewController = [storyboard instantiateInitialViewController];
        } @catch (NSException *exception) {
        }
        
        if (!launchViewController) {
            @try {
                UIView *view = [[[NSBundle mainBundle] loadNibNamed:storyboardName owner:nil options:nil] firstObject];
                [view setFrame:[UIScreen mainScreen].bounds];
                launchViewController = [UIViewController new];
                [launchViewController.view addSubview:view];
            } @catch (NSException *exception) {
            }
        }
    }

    return launchViewController;
}

五鸽疾、其余代碼

現(xiàn)在使用UIWindow來啟動(dòng)圖。省略的代碼上文查找训貌。

+ (BOOL)size1:(CGSize)size1 equleToSize2:(CGSize)size2 {
    ...
}

+ (UIViewController *)nibLaunchViewController {
    ...
}

+ (UIView *)picLaunchView { 
    ...
}

+ (NSString *)launchImageName { 
    ...
}

+ (UIViewController *)defaultLaunchViewController {
    UIViewController *launchViewController = [self nibLaunchViewController];
    if (launchViewController) {
        return launchViewController;
    }
    
    UIView *picLaunchView = [self picLaunchView];
    if (picLaunchView) {
        launchViewController = [UIViewController new];
        [launchViewController.view addSubview:picLaunchView];
    }
    
    return launchViewController;
}

+ (void)showLaunchView {    
    UIViewController *controller = [self defaultLaunchViewController];
    if (!controller) {
        controller = [UIViewController new];
        [controller.view setBackgroundColor:[UIColor whiteColor]];
    }
    
    UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    window.rootViewController = rootController;
    [window makeKeyAndVisible];
}

  • 通過[obj showLaunchView]直接顯示制肮;
  • 優(yōu)先級(jí)storyboard > xib > launch image;
  • 支持iPhone旺订、iPad弄企,橫屏超燃、豎屏区拳。

本文又臭又長(zhǎng),感謝再次品味~~~~

其實(shí)意乓,其實(shí)樱调,在window顯示的地方還是有點(diǎn)細(xì)節(jié),本文可以讓你做完事情届良,但不是做好笆凌。

B的口頭禪是“不要在意這些細(xì)節(jié)”,然而又是個(gè)非常注重細(xì)節(jié)的人士葫。

本來打住的話題乞而,重新打開,發(fā)現(xiàn)有更多想說的慢显。下篇預(yù)告《iOS啟動(dòng)圖你需要關(guān)注的小問題》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末爪模,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子荚藻,更是在濱河造成了極大的恐慌屋灌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件应狱,死亡現(xiàn)場(chǎng)離奇詭異共郭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)疾呻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門除嘹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人岸蜗,你說我怎么就攤上這事尉咕。” “怎么了散吵?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵龙考,是天一觀的道長(zhǎng)蟆肆。 經(jīng)常有香客問我,道長(zhǎng)晦款,這世上最難降的妖魔是什么炎功? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮缓溅,結(jié)果婚禮上蛇损,老公的妹妹穿的比我還像新娘。我一直安慰自己坛怪,他們只是感情好淤齐,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著袜匿,像睡著了一般更啄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上居灯,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天祭务,我揣著相機(jī)與錄音,去河邊找鬼怪嫌。 笑死义锥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的岩灭。 我是一名探鬼主播拌倍,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼噪径!你這毒婦竟也來了柱恤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤熄云,失蹤者是張志新(化名)和其女友劉穎膨更,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缴允,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荚守,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了练般。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矗漾。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖薄料,靈堂內(nèi)的尸體忽然破棺而出敞贡,到底是詐尸還是另有隱情,我是刑警寧澤摄职,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布誊役,位于F島的核電站获列,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蛔垢。R本人自食惡果不足惜击孩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鹏漆。 院中可真熱鬧巩梢,春花似錦、人聲如沸艺玲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饭聚。三九已至忌警,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間若治,已是汗流浹背慨蓝。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工感混, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留端幼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓弧满,卻偏偏與公主長(zhǎng)得像婆跑,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子庭呜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

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