在昨天的練習中,我們成功在 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 元件綁定:從畫面拖拉到程式互動!》