iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 6
1
Mobile Development

諸神黃昏下的 iOS 工程師系列 第 6

D6 - 讓我們在啟動畫面(Launch Screen)做一些怪怪的事吧

讓我們一起來看如何在 Launch Page 實現特殊功能吧!

? 隕石小故事

當我在接案和隕石開發時,有時候會碰到需要再 LaunchScreen 上面實現一些特殊功能,像是「能不能多停留幾秒啊?」、「可不可以在上面做個動畫啊?」、「可以在幾秒之後顯示一個按鈕嗎?」等等諸如此類的需求,但是我們又無法再 LaunchScreen 編寫程式碼,那該怎麼實現它呢?

Overview

因為 LaunchScreen 是屬於靜態的內容,我們又無法在上面編寫程式碼,所以無法在 LaunchScreen 上做一些操作。但是我們可以透過一些特殊的方法(邪魔歪道?)來控制 LaunchScreen,使其實現我們要的功能。這邊讓我教各位幾招在 LaunchScreen 上可以做的操作。


實作 LaunchScreen

首先我們先在 LaunchScreen.storyboard 上簡單做一個啟動畫面,方便我們後面實作:

|在 LaunchScreen 上多停留幾秒

在這邊因為 LaunchScreen 是最一開始的畫面,如果想要在上面多停留幾秒,我們可以在 AppDelegatedidFinishLaunchingWithOptions 加上一個 sleep 的函數讓我們的 APP 凍結(鎖住),並且畫面停留在 LaunchScreen 上,如此一來就能實現停留多秒的效果了。

這邊我們可以使用 Thread.sleep 或是 sleep 都可以達成相同的凍結效果。

效果展示:


|獲取 LaunchScreen,並且在上面動點手腳

因為 LaunchScreen 也算是一個 Storyboard,所以我們可以透過 UIStorybaord 的方式來訪問其中的 ViewController,而因為我們這個 LaunchScreen 的 Storyboard 只有一個 viewController 並且為 initail viewController,所以我們可以透過 instantiateInitialViewController 來獲取他即可:

let launchScreen = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController()

接著那我們要如何獲取這個 viewController 上的元件呢?LaunchScreen 是不能夠設置 Custom Classnames 的。

在這邊,我會使用 tag 的方式來實現,首先在該 viewController 的畫面中,為你想要操作的元件設置 tag,之後我們可以透過上面的 launchScreen 使用 viewWithTag 方式來獲取該元件:

那既然都知道如何獲得這些東西之後,那讓我們來寫個動畫的 function 吧:

在我們獲取 launchScreen 後,使用 addSubViewlaunchScreen.view 加入到我們 ViewControllerview 上,並且在最後動畫完成時,將這個 launchScreen.view 給移除。

效果展示:

|好麻煩,自己做一個 Launch Screen 最快

如果我們想要讓 LaunchScreen 可以與我們畫面相似並且轉場順暢,我們其實可以使用我們原有的 storyboard 新增一個 ViewController 來作為 LaunchScreen 即可。

我們可以在 App Icons and Launch Images 的 Launch Screen File 選擇我們要作為 LaunchScreen 的檔案,這邊為了保持畫面一致性,我們會選擇與 Main Interface 相同的Storyboard/Xib。

接著我們到 Main.storyboard 新增一個 ViewController,並且讓他成為 initail viewController,之後會做為我們的 LaunchSreen。

接著我們可以為他新增一個 class,此時,你可以拖拉元件到其中,並且在裡面編寫你想實現的動畫:

動畫結束後,我們會使用 performSegue 來將畫面移動下一個 viewController 上。

效果展示:

注意
但是這種方式如果這個 viewController 只當 LaunchScreen 使用的話,那他其實會一直留在畫面的階層中,因為他沒有被 dismiss 。但如果單純只是為了畫面一致性的話倒沒有問題。

因此我們也可以將 LaunchScreen.storyboard 的畫面跟某個 Storyboard 或 Xib 中的某個畫面統一,並且在 LaunchScreen 結束時,將某個作為 LaunchScreen 的 viewController 透過 initial viewcontroller 給 present 出來,如此一來就能夠解決這個無法被釋放的困擾。

所以首先我們要設定我們原本的 ViewController 做為 initial viewController,並且將它與作為 LaunchScreen 的 viewController 設置一個 Segue,並且 KindPrsentModallyPrsentationOver Current Context,並且取消 Animates(因為不需要由下往上飛入的動畫)。

接著我們到 LaunchAnimationViewController 設定在 viewDidAppear 的時候觸發動畫,並且在結束之後 dismiss 自己:

我們原本的流程是:

  1. LaunchAnimationViewController 作為啟動畫面
  2. Initial viewController 為 LaunchAnimationViewController 並且執行動畫
  3. 動畫結束後,移動到下一個畫面,但是原有的 LaunchAnimationViewController 沒有被移除

而我們現在變成:

  1. 一樣用 LaunchScreen.storyboard 的畫面作為啟動畫面
  2. 讓 initial viewController 把 LaunchAnimationViewControllerpresent 出來
  3. LaunchAnimationViewController 執行動畫
  4. 動畫結束後,把 LaunchAnimationViewControllerdismiss

如此一來我們就能夠使用自己新增的啟動畫面,並且不用擔心會有無法釋放的問題。

效果展示:


Summary

有時候都覺得以正常的邏輯來做根本不可能,但是實際去科普之後卻發現有許多千奇百怪,妖魔鬼怪的做法可以實現 ?,這可能也算是寫程式中的樂趣了吧?!希望各位讀者閱讀之後可以在 Launch Screen 做更多怪怪的事,也歡迎跟我分享更好的做法。


上一篇
D5 - 串接好 API 後,別忘好好整理一番
下一篇
D7 - 專案檔案結構亂糟糟,只好 cmd+Q ?
系列文
諸神黃昏下的 iOS 工程師31

尚未有邦友留言

立即登入留言