网络知识 娱乐 iOS-启动项目(一)设置 rootViewController(22年4月22日更新可用)

iOS-启动项目(一)设置 rootViewController(22年4月22日更新可用)

摘要

刚创建一个新的项目,在 AppDelegate 中设置 rootViewController 来确定应用的首页是一个最基本的处理,因为是不常操作的处理,所以容易忽略其中的某个步骤,导致无法设置成功。所以记录下来,以备快速查找。

刚创建一个 iOS 项目,会先设置应用的 rootViewController,也就是应用的首页。一般的操作代码如下:

// UIViewController 为首页控制器
let homeNav = UINavigationController.init(rootViewController: UIViewController.init())
window?.rootViewController = homeNav
window?.makeKeyAndVisible()

这三行代码需要写在 AppDelegateapplication(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 函数中。

当完成以上步骤之后,会发现这里没有 window 对象,那就需要在 AppDelegate 中设置 window 属性变量:

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

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

到这里,项目工程就没有报错,就正常运行应用,漫长的编译、初始化和启动应用的过程后,发现首页并不是自己设置的控制器。

接下来排查问题,最上面的三行代码也是执行了,就是打断点看 window 对象,window 也不是 nil。查找好久,发现还需要在做一步处理。

就是到项目工程中,选择 Info 选项,看到 Custom iOS Target Properties 列表中,删除 Application Scene Manifest 选项。

window-image

然后在 AppDelegate.swift 文件中看一下有没有如下两个函数,如果有就删除一下:

     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.
    }

这时候,再运行工程,可以成功的跳转到自己设置的首页了。

那么,Application Scene Manifest 是什么,为什么会影响到设置首页呢?

查找开发文档,看到 UIApplicationSceneManifest 选项的解释,在详细的解释中找到了答案:若在 plist 文件中设置这个选项,那么应用就支持 scenes,并且不能在 AppDelegate 中处理页面的切换。

Discussion

The presence of this key indicates that the app supports scenes and does not use an app delegate object to manager transitions to and from the foreground or background.

新创建项目工程的时候,会发现除了 AppDelegate.swift 文件之外,还有一个 SceneDelegate.swift 文件。并且这个文件只能在 iOS 13 及以上才可以使用。现在还不是很确定这两个文件的联系和区别,在什么样的场景中使用 SceneDelegate 对象,等后面再多了解些,再去使用它。

题外话

时间仓促,说的东西可能不全面,在你查看的过程中遇到什么问题,评论区给我留言,我会尽快回复