[Swift] AppDelegate 與 SceneDelegate

先說結(jié)論:
SceneDelegate 用于 iPad 分屏 APP 開發(fā), 目前 iPhone 沒有分屏

純代碼, 不使用 StoryBoardxib

在 Xcode 11 和 iOS 13 中新增了 SceneDelegate, SceneDelegatescene 代替了 AppDelegatewindow

  • window 就是應用程序, 只有一個, 所有操作, 都在 window 中
  • scene 場景, 應用程序可以有多個場景, 每個場景都有一個 window

UISceneDelegate
Working with Window Scenes
Supporting Multiple Windows on iPad
Support side-by-side instances of your app’s interface and create new windows.
使用窗口場景
支持iPad上的多個窗口
支持應用界面的并行實例并創(chuàng)建新窗口。

AppDelegate (Xcode10 / iOS12 及之前)

AppDelegate 全權(quán)處理 App生命周期 和 UI生命周期

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    
    let nav = UINavigationController(rootViewController: ViewController())
    
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = nav
    window?.makeKeyAndVisible()
    
    return true
}

// MARK: UIApplicationDelegate

@available(iOS 2.0, *)
optional func applicationDidBecomeActive(_ application: UIApplication)

@available(iOS 2.0, *)
optional func applicationWillResignActive(_ application: UIApplication)

@available(iOS 4.0, *)
optional func applicationDidEnterBackground(_ application: UIApplication)

@available(iOS 4.0, *)
optional func applicationWillEnterForeground(_ application: UIApplication)

AppDelegate + SceneDelegate (Xcode11 / iOS13)

  • AppDelegate 處理 App生命周期 和 SceneSession 生命周期
  • SceneSession 負責 UI生命周期

新項目變化

  • AppDelegate.swift 只配置 UISceneConfiguration, 不再管理 window,
// MARK: UISceneSession Lifecycle

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

// 退出場景, 不會被重新連接
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
  • 新增了 SceneDelegate.swift 文件, 管理場景的生命周期掂名,處理各種響應
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    // 與 didFinishLaunchingWithOptions 類似, 配置場景
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        
        guard let windowScene: UIWindowScene = (scene as? UIWindowScene) else { return }
        let window = UIWindow(windowScene: windowScene)
        self.window = window
        
        let nav = UINavigationController(rootViewController: ViewController())
        window.rootViewController = nav
        
        window.makeKeyAndVisible()
    }

    // 當場景與app斷開連接 (還可能重新連接)
    func sceneDidDisconnect(_ scene: UIScene) {
        // Called as the scene is being released by the system.
        // This occurs shortly after the scene enters the background, or when its session is discarded.
        // Release any resources associated with this scene that can be re-created the next time the scene connects.
        // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
    }

    // 與 AppDelegate 的 applicationDidBecomeActive 類似
    func sceneDidBecomeActive(_ scene: UIScene) {
        // Called when the scene has moved from an inactive state to an active state.
        // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
    }

    // 與 AppDelegate 的 applicationWillResignActive 類似
    func sceneWillResignActive(_ scene: UIScene) {
        // Called when the scene will move from an active state to an inactive state.
        // This may occur due to temporary interruptions (ex. an incoming phone call).
    }

    // 與 AppDelegate 的 applicationWillEnterForeground 類似
    func sceneWillEnterForeground(_ scene: UIScene) {
        // Called as the scene transitions from the background to the foreground.
        // Use this method to undo the changes made on entering the background.
    }

    // 與 AppDelegate 的 applicationDidEnterBackground 類似
    func sceneDidEnterBackground(_ scene: UIScene) {
        // Called as the scene transitions from the foreground to the background.
        // Use this method to save data, release shared resources, and store enough scene-specific state information
        // to restore the scene back to its current state.
    }
}
  • Info.plist 新增了 Application Scene Manifest
<plist version="1.0">
<dict>
    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Main</string>
                </dict>
            </array>
        </dict>
    </dict>
</dict>
</plist>

新項目刪除 SceneDelegate

  1. 刪除 SceneDelegate.swift
  2. 刪除 Info.plist 新增了 UIApplicationSceneManifest
  3. 刪除 AppDelegate.swift 中的 scene 相關(guān)方法
  4. 修改 LaunchScreen.storyboard 啟動頁面
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涤躲,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子尤慰,更是在濱河造成了極大的恐慌,老刑警劉巖旬牲,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件优训,死亡現(xiàn)場離奇詭異猎贴,居然都是意外死亡班缎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門她渴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來达址,“玉大人,你說我怎么就攤上這事趁耗〕吝耄” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵苛败,是天一觀的道長满葛。 經(jīng)常有香客問我,道長罢屈,這世上最難降的妖魔是什么嘀韧? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮缠捌,結(jié)果婚禮上锄贷,老公的妹妹穿的比我還像新娘。我一直安慰自己曼月,他們只是感情好谊却,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哑芹,像睡著了一般炎辨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聪姿,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天碴萧,我揣著相機與錄音,去河邊找鬼咳燕。 笑死勿决,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的招盲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼嘉冒,長吁一口氣:“原來是場噩夢啊……” “哼曹货!你這毒婦竟也來了咆繁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤顶籽,失蹤者是張志新(化名)和其女友劉穎玩般,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體礼饱,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡坏为,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了镊绪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匀伏。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蝴韭,靈堂內(nèi)的尸體忽然破棺而出够颠,到底是詐尸還是另有隱情,我是刑警寧澤榄鉴,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布履磨,位于F島的核電站,受9級特大地震影響庆尘,放射性物質(zhì)發(fā)生泄漏剃诅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一驶忌、第九天 我趴在偏房一處隱蔽的房頂上張望矛辕。 院中可真熱鬧,春花似錦位岔、人聲如沸如筛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽杨刨。三九已至,卻和暖如春擦剑,著一層夾襖步出監(jiān)牢的瞬間妖胀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工惠勒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赚抡,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓纠屋,卻偏偏與公主長得像涂臣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355