iOS: 맨 앞에 화면 보이기/맨 앞에 화면 알기

10290 단어 SwiftiOS
iOS 응용 프로그램의 맨 앞에 있는 UIVIewController를 요약합니다.
※ 최신(2022년 2월) 소스 코드는 여기에 기재되어 있습니다.
https://www.fuwamaki.com/article/258

맨 앞에 있는 UIVIew Controller는 두 가지가 있어요.

  • UIApplication.shared.keyWindow?.rootViewController
  • UIApplication.shared.delegate?.window??.rootViewController
  • 가장 앞의 UIVIew Controller를 획득하는 방법 2가지
    그것들을 사용할 때 구별하기 위해서.
    생각이 이 기사를 쓰는 시작이다.
    다른 방법을 아는 사람이 있으면 알려주세요.
    그리고 다음은 자신의 해석이 많으니 잘못이 있으면 알려주세요.

    UIApplication의 keyWindow


    UIApplication.shared.keyWindow의 ref
    https://developer.apple.com/documentation/uikit/uiapplication/1622924-keywindow
    This property holds the UIWindow object in the windows array that is most recently sent the makeKeyAndVisible() message.
    최근에 표시된 창이라고 설명합니다.
    이런 상황에서 키 윈도우.rootViewController
    최근에 표시된 UIVIew Controller가 됩니다.
    makiKey AndVisible의 ref

    UIApplication Delegate의 창


    UIApplication.shared.delegate?.윈도우ref
    https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623056-window
    This property contains the window used to present the app’s visual content on the device’s main screen.
    Implementation of this property is required if your app’s Info.plist file contains the UIMainStoryboardFile key. Fortunately, the Xcode project templates usually include a synthesized declaration of the property automatically for the app delegate. The default value of this synthesized property is nil, which causes the app to create a generic UIWindow object and assign it to the property. If you want to provide a custom window for your app, you must implement the getter method of this property and use it to create and return your custom window.
    이것은 장치의 맨 앞에 보기를 표시하는 창이라고 설명합니다.
    이 창을 사용하면 MainStoryboard가 Info가 됩니다.plist
    설정을 전제로 한 것 같습니다.

    구분 사용 요약


    맨 앞의 UIVIew Controller의 사용은 주로
  • 맨 앞에 있는 화면이 궁금하다
  • 화면 맨 앞에 보이고 싶다
  • 의 규격화 거리의 멱 함수.이를 바탕으로 표현하면 이런 느낌이다.
    맨 앞에 화면이 궁금해요.
    저는 화면을 맨 앞에 놓고 싶어요.
    keyWindowTopViewController


    topViewController
    ×

    ※keyWindowTopViewController... UIApplication.shared.keyWindow?.rootViewController※topViewController... UIApplication.shared.delegate?.window??.rootViewController솔직히 key Windows Top View Controller만 이 두 역할을 동시에 할 수 있다.
    그러나 나는 다음과 같은 작용이 더 믿을 만한지 스스로 검증했다.
  • 맨 앞의 화면을 알고 싶으면 keyWindows TopView Controller
  • 를 사용하십시오
  • 화면을 맨 앞에 표시하려면 topViewController
  • 를 사용하십시오.

    key Windows TopView Controller에서 맨 앞에 화면이 표시되고 일치하지 않는 경우


    창을 keyWindowsTopViewController로 설정할 수 있습니다.
    이 창에 다른 화면을 표시하려면keyWindowTopViewController.present 에서 화면 표시
    다음과 같이 일치하지 않습니다.

    왼쪽은 이번 대상 상황, 오른쪽은 topView Controller 사용 상황
    rootViewController 결과를 내보냅니다.
    왼쪽은 거의 nil,view입니다. 왠지 얻을 수 밖에 없습니다.
    이게 무슨 상황이라고 해야 되나?
    표시하고 싶은 화면이 표시되지만 아무것도 조작할 수 없는 상태입니다.
    꼭 이렇게 되는 건 아닌 것 같아요.
    keyWindowsTopViewController에서 맨 앞에 화면 보이기
    피하는 게 좋을 것 같아서요.

    결론 기반 extension


    상기 상황을 고려하여 우리는 매우 편리할 수 있는 extension을 고려했다.
    둘 다 맨 앞의 실현이다.
    import UIKit
    
    extension UIApplication {
        // 最前面の画面を知るために用いる。
        class func keyWindowTopViewController(on controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
            if let navigationController = controller as? UINavigationController {
                return keyWindowTopViewController(on: navigationController.visibleViewController)
            }
            if let tabController = controller as? UITabBarController,
                let selected = tabController.selectedViewController {
                return keyWindowTopViewController(on: selected)
            }
            if let presented = controller?.presentedViewController {
                return keyWindowTopViewController(on: presented)
            }
            return controller
        }
    
        // 最前面に画面を表示するために用いる。
        class func topViewController() -> UIViewController? {
            guard let rootViewController = UIApplication.shared.delegate?.window??.rootViewController else { return nil }
            var presentedViewController = rootViewController.presentedViewController
            if presentedViewController == nil {
                return rootViewController
            } else {
                while presentedViewController?.presentedViewController != nil {
                    presentedViewController = presentedViewController?.presentedViewController
                }
                return presentedViewController
            }
        }
    }
    
    사용 예:
    if UIApplication.keyWindowTopViewController() is HogeViewController {
        //処理
        return
    }
    
    UIApplication.topViewController()?.present(hogeViewController, animated: true, completion: nil)
    

    총결산


    "아니오, 0의 예외가 있기 때문에 느낌이 다르다"는 지적이 있으면 알려주세요.
    다른 사람도 꼭 써주세요.

    참고 자료

  • https://qiita.com/Simmon/items/80dbf50bc85c527f10f3
  • https://qiita.com/maebaru/items/ae954b19ad334f990538
  • 좋은 웹페이지 즐겨찾기