一般在用 Xcode 創新專案的時候,會預設使用 Main.storyboard 來作為我們設計 UI 畫面的地方
但這樣有個缺點,就是當你 Storyboard 上面有很多畫面的時候,Storyboard 會需要比較長的時間載入,以及在開發上如果要對某個畫面做動作時,有時候會很難處理,讓開發效率降低
所以通常會建議改用 Xib 來做 UI 畫面設計,這樣每個畫面、每個元件都會是一個檔案
在開發上會比較好處理,開發效率也會比較高
但沒有說用 Storyboard 做 UI 畫面設計就不好,還是要依實際狀況來做變通~
首先先到專案設置的檔案 (檔名:專案名稱.xcodeproj),找到「Deployment Info」
找到「Main Interface」,然後將他清空
再切到「Info.plist」,找到「Application Scene Manifest」,將其全部選項都點開
全部點開後,會看到「Storyboard Name」這一行,然後把它整行刪掉,如下圖
接著,再將左側的專案檔案列表裡面的「ViewController.swift、Main.storyboard」這兩個檔案刪掉
接著先建立一個資料夾,來放第一個畫面的檔案,我們取名為「MainVC」,然後在裡面新增名為「MainVC.swift、MainVC.xib」的檔案
把「Also create XIB file」打勾,就會自動產生這個 ViewController 的 xib 檔案,來讓我們進行 UI 畫面設計,現在我們左側的專案檔案列表應該會長這樣
接下來,終於要來寫 Code 了~
如果你的 App 最低的系統安裝版本是 iOS 13 以前的話,像是 iOS 12、iOS 11 之類的
那你要在「AppDelegate.swift 跟 SceneDelegate.swift」這兩個檔案加入下方的 Code
如果如果你的 App 最低的系統安裝版本是 iOS 13 (含)以上的話
那就直接在「SceneDelegate.swift」這個檔案加入下方的 Code
會有這樣的區別是因為 SceneDelegate.swift 是只有 iOS 13 (含)以上版本才會去讀這個檔案,iOS 13 以下的版本則是會去讀 AppDelegate.swift 這個檔案
所以說,如果你要讓 App 可以順利在 iOS 13 以前跟以後的系統都可以順利開啟的話,就要在 AppDelegate.swift 跟 SceneDelegate.swift 這兩個檔案裡都加入下方的程式碼
App 最低的系統安裝版本是 iOS 13 以前的話,像是 iOS 12、iOS 11 之類的↓
// AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let rootVC = MainVC(nibName: "MainVC", bundle: nil)
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = rootVC
window?.makeKeyAndVisible()
return true
}
...
}
// SceneDelegate.swift
@available(iOS 13.0, *) // 這行加在 class 上面
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let rootVC = MainVC(nibName: "MainVC", bundle: nil)
let navigationController = UINavigationController(rootViewController: rootVC)
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
}
...
}
App 最低的系統安裝版本是 iOS 13 (含)以上的話↓
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let rootVC = MainVC(nibName: "MainVC", bundle: nil)
let navigationController = UINavigationController(rootViewController: rootVC)
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
}
...
}
本篇的範例程式碼:GitHub