코드에서 NavigationController를 생성했을 때 빠졌고 해결책

17310 단어 Swift

버전



・Xcode12.5.1
・Swift5
· iOS 14.5

개요



코드에서 NavigationController를 생성 할 때 오류는 발생하지 않지만 NavigationController가 생성되지 않은 경우의 대응에 대해

iOS13 이후로 앱의 기동 순서가 바뀌었기 때문에 빠졌다고 생각한다.

해결 전 코드



AppDelegate.swift에서 NavigationController 생성 구현

AppDelegate.swift
import UIKit
import CoreData

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    //
    var window: UIWindow?
    var navigationController: UINavigationController?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // 以下navigationControllerを生成するコード
        let viewController: ViewController = ViewController()
        navigationController = UINavigationController(rootViewController: viewController)
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = navigationController
        self.window?.makeKeyAndVisible()

        return true
    }
}

실행 결과





※적색 프레임 부분에서 view를 계층적으로 보고 디버그

위 그림에서 NavigationController가 생성되지 않았음을 알 수 있습니다.

대처법



・iOS12 이전의 경우

①SceneDelegate.swift에 @available (iOS 13.0, *) 추가

SceneDelegate.swift
import UIKit

// 追記部分
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    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 _ = (scene as? UIWindowScene) else { return }

    }
                         ~以下略~
}


②AppDelegate.swift에 @available (iOS 13.0, *)등을 추기한다

AppDelegate.swift
import UIKit
import CoreData

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // 以下2行を追加
    var window: UIWindow?
    var navigationController: UINavigationController?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // 以下UINavigationController生成の実装部分
        let viewController: ViewController = ViewController()
        navigationController = UINavigationController(rootViewController: viewController)
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = navigationController
        self.window?.makeKeyAndVisible()

        return true
    }

// @available(iOS 13.0, *)を追記する
@available(iOS 13.0, *)
    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)
    }

    @available(iOS 13.0, *)
    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.

    }
}

・iOS13 이후의 경우

③ SceneDelegate에서 UINavigationController 생성 코드 구현

SceneDelegate.swift
import UIKit

@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?
    // UINavigationController型の変数を宣言
    var navigationController: UINavigationController?

    @available(iOS 13.0, *)
    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 _ = (scene as? UIWindowScene) else { return }

        // // 以下UINavigationController生成の実装部分
        let viewController: UIViewController = SampleViewController()
        navigationController = UINavigationController(rootViewController: viewController)
        self.window = UIWindow(windowScene: scene as! UIWindowScene)
        self.window?.rootViewController = navigationController
        self.window?.makeKeyAndVisible()

    }
            ~以下略~
}



솔루션 실행 후 결과





UINavigationController의 생성을 확인할 수 있다

참고로 한 기사



storyboard를 사용하지 않고 Swift로 네비게이션 바 만들기(UINavigationController라든지)
iOS13의 SceneDelegate 주변 앱 시작 순서
Storyboard를 사용하지 않는 iOS 앱 개발

끝에



같은 일로 곤란한 사람의 도움이 되면 다행입니다!
만약 잘못되어 있는 부분이 있으면, 지적해 주시면 기쁩니다!

좋은 웹페이지 즐겨찾기