在昨天的練習中,我們成功在 Xcode 中建立了自己的第一個 iOS App 專案。當你打開這個專案時,會發現 Xcode 自動幫我們產生了一些重要的檔案,其中最關鍵的兩個就是:AppDelegate.swift 和 SceneDelegate.swift。
它們不只是預設產生的程式碼檔案,而是整個 App 的「生命中樞」與「畫面總監」,負責管理從啟動到退出的所有流程。
今天,我們將一起拆解這兩個檔案,了解它們的職責與運作邏輯,並實際動手,將專案的介面架構從 Storyboard 轉換為更靈活的 Xib,為日後的 UI 操作打下基礎。
AppDelegate 與 SceneDelegate 的職責與作用Storyboard 與 Xib 的差異與使用場景Storyboard 專案轉換為 Xib 架構AppDelegate.swift 是整個 App 的總指揮,負責處理與 App 狀態有關的事件。雖然它不直接處理畫面,但所有重大流程都會先經過它。
常見方法解析:
| 方法名稱 | 觸發時機 | 建議用途 |
|---|---|---|
application(_:didFinishLaunchingWithOptions:) |
App 啟動時 | 初始化作業,如資料庫設定、啟用通知、建立主視窗等 |
application(_:configurationForConnecting:options:) |
新增 UI 畫面(Scene)時被呼叫 | 設定新場景的建立邏輯 |
application(_:didDiscardSceneSessions:) |
當場景被關閉或釋放時 | 清理資源或進行紀錄 |
從 iOS 13 起,一個 App 可以擁有多個畫面場景(Scene),每個 Scene 都由 SceneDelegate.swift 來管理。
常見方法解析:
| 方法名稱 | 觸發時機 | 建議用途 |
|---|---|---|
scene(_:willConnectTo:options:) |
畫面初始化階段 | 建立主視窗 (UIWindow),指定初始畫面 |
sceneDidDisconnect(_:) |
當場景關閉或系統釋放場景時 | 清除場景資源或進行收尾處理 |
sceneDidBecomeActive(_:) |
畫面從非活動狀態轉為活躍狀態時 | 恢復動畫、計時器,重新啟動暫停任務 |
sceneWillResignActive(_:) |
畫面即將變為非活動狀態(如接電話) | 暫停動畫、停止即時更新 |
sceneWillEnterForeground(_:) |
App 從背景返回前景時 | 刷新資料、更新畫面內容 |
sceneDidEnterBackground(_:) |
畫面退到背景時 | 儲存資料、釋放不必要資源 |
Xcode 預設使用 Storyboard 來設計畫面,但我們會改採更模組化的 Xib 檔案,讓每個畫面獨立、可維護性更高。
| 項目 | Storyboard | Xib |
|---|---|---|
| 結構 | 多個畫面集中在同一檔案 | 每個畫面對應一個 Xib |
| 優點 | 可視化流程、方便快速建構 | 檔案小巧、好管理、減少衝突 |
| 缺點 | 專案一大容易變得雜亂、難維護 | 缺少畫面流程的整體視覺呈現 |
| 適合情境 | 簡單 App、Prototype 開發 | 中大型 App、多人協作開發 |
我們的目標:接下來的步驟,目的是切斷 Xcode 預設的「透過 Storyboard 自動載入 App 畫面」的流程,然後在SceneDelegate.swift中,用我們自己的程式碼來「手動接管」,明確指定MainViewController.xib作為 App 啟動後的第一個畫面。
這個過程非常技術性,請務必完全依照步驟操作,任何一個小地方打錯字都可能導致 App 黑畫面喔!
刪除 Main.storyboard 和 ViewController.swift。
之後的檔案管理畫面應該長這樣:

打開專案,切換到 Info 分頁
展開:Application Scene Manifest > Scene Configuration > Window Application Session Role > Item 0 (Default Configuration)
刪除 Storyboard Name 的設定行:
切換到 Build Settings
搜尋 UIKit
清空 UIKit Main Storyboard File Base Name 的值:
對專案資料夾 test 按右鍵,點擊 New File from Template:
選取 Cocoa Touch Class 後,接著按下 Next:
Subclass of 下拉選單選擇 UIViewController,接著命名為 MainViewController,並勾選 Also create XIB file。
完成之後按下 Next:
確認檔案儲存位置後,按下 Create:
完成這一步動作之後,就會在左側的檔案管理看見 MainViewController.swift 和 MainViewController.xib:
找到 scene(_:willConnectTo:) 這一個 func ,改成以下內容(覆蓋原始內容):
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
// 使用 Xib 檔案來初始化 MainViewController
// 這裡的 nibName 字串,必須和你的 .xib 檔名一模一樣
let rootVC = MainViewController(nibName: "MainViewController", bundle: nil)
let navigationController = UINavigationController(rootViewController: rootVC)
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
}
MainViewController 當作起始畫面UINavigationController 包裝畫面:
UINavigationController就像一個容器,能幫助我們管理畫面的層級,讓我們未來可以輕鬆實現「下一頁」、「返回上一頁」等功能。今天,我們一起揭開了 App 啟動的神秘面紗,深入了專案的「引擎室」!你不僅學會了 AppDelegate 與 SceneDelegate 的核心職責,更重要的是,你親手完成了從 Storyboard 到 XIB 的架構大改造。
這是一次硬核但極具價值的操作。從今天起,你不再只是一個使用者,而是真正掌握了 App 啟動流程的主導權。這個基礎將讓你在未來的 UI 開發中,擁有更高的自由度與靈活性!
今天辛苦的架構改造,就是為了明天能自由地創作!我們終於要在畫布上,揮灑我們的第一筆色彩了。
明天,我們將正式進入 Xib 的視覺化設計介面,你將學會如何拖曳出 UI 元件,打造 App 的外觀。但更神奇的是,我們要扮演「魁儡師」的角色,為畫面上的元件賦予生命!
我們會學習用 IBOutlet 為元件命名,並用 IBAction 為它們綁上動作的絲線。當使用者點擊按鈕時,你的程式碼就會收到信號並做出反應。這將是你第一次串連起「畫面」與「邏輯」,讓 App 真正「活」起來的關鍵一課!
敬請期待《Day 17|Xcode 元件綁定:從畫面拖拉到程式互動!》