一、SceneDelegate與AppDelegate
在從iOS 13開始,蘋果引入了SceneDelegate來管理多個場景。與此同時,AppDelegate的角色變成了應用程序生命周期的管理者,SceneDelegate則負責管理每個場景的生命周期。
AppDelegate是整個應用程序的入口,當應用程序啟動時,會先調用AppDelegate里的函數。然後,當需要創建Scene時,就會創建一個新的代表當前場景的SceneDelegate。換句話說,SceneDelegate是與場景相關的,而AppDelegate是與整個應用程序相關的。
二、SceneDelegate調用其他控制器函數
SceneDelegate可以與其他控制器進行交互,調用它們的函數,來完成一些事情。
下面是一個例子,當某個用戶點擊了一個菜單按鈕,就會出現一個選項卡視圖。在這個過程中,SceneDelegate需要調用UITabBarController的present函數來打開選項卡視圖。
import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? var tabBarController: UITabBarController? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) tabBarController = UITabBarController() let firstViewController = UIViewController() let secondViewController = UIViewController() tabBarController?.viewControllers = [firstViewController, secondViewController] window.rootViewController = tabBarController self.window = window window.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { } func sceneDidBecomeActive(_ scene: UIScene) { } func sceneWillResignActive(_ scene: UIScene) { } func sceneWillEnterForeground(_ scene: UIScene) { } func sceneDidEnterBackground(_ scene: UIScene) { } func presentFilterMenu() { guard let tabBarController = self.tabBarController else { return } let filterViewController = FilterViewController() let navigationController = UINavigationController(rootViewController: filterViewController) navigationController.modalPresentationStyle = .overFullScreen tabBarController.present(navigationController, animated: true, completion: nil) } }
在上面的代碼中,我們在SceneDelegate里創建了一個UITabBarController,並把兩個UIViewController作為其子視圖控制器。當我們需要打開選項卡視圖時,在SceneDelegate里調用了presentFilterMenu函數,這個函數會創建FilterViewController,然後用UINavigationController包裝一下,最後調用UITabBarController的present函數來打開選項卡視圖。
三、SceneDelegate相比AppDelegate的優勢
使用SceneDelegate,我們可以更好地管理多個場景。在iOS 13之前,每個應用程序只有一個AppDelegate,而現在,一個應用程序可以擁有多個SceneDelegate。我們可以讓每個SceneDelegate只關心其自身的邏輯,而不必把所有的邏輯都放在一個AppDelegate里處理。
如果我們有一個包含多個視圖控制器的場景,而這些視圖控制器都需要進行網路請求,我們可以把網路請求相關的代碼放在一個網路請求管理器中。然後,我們可以在每個視圖控制器中調用這個網路請求管理器,並讓SceneDelegate來初始化它。
import UIKit class NetworkManager { static let shared = NetworkManager() func fetchData() { ... } } class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? var tabBarController: UITabBarController? var networkManager: NetworkManager? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) tabBarController = UITabBarController() let firstViewController = ViewController() let secondViewController = ViewController() networkManager = NetworkManager.shared firstViewController.networkManager = networkManager secondViewController.networkManager = networkManager tabBarController?.viewControllers = [firstViewController, secondViewController] window.rootViewController = tabBarController self.window = window window.makeKeyAndVisible() } }
在上面的代碼中,我們創建了一個NetworkManager,這是一個用來管理網路請求的類。我們在SceneDelegate里初始化了這個NetworkManager,然後在每個ViewController中調用。
四、結語
在本文中,我們詳細介紹了SceneDelegate的作用和優勢,以及如何在SceneDelegate中調用其他控制器函數。SceneDelegate管理多個場景,使得應用程序變得更加靈活和易於維護。通過SceneDelegate,我們可以實現更好的代碼隔離和邏輯分離。
原創文章,作者:XKRL,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/144561.html