Clean way to force view to load subviews early

前端 未结 6 1057
南方客
南方客 2021-01-07 23:06

Recently I wrote some code where I tried to refer to an outlet on a UIViewController I\'d just instantiated with [storyboard instantiateViewControllerWith

相关标签:
6条回答
  • 2021-01-07 23:19

    On iOS 9 or newer, one can use:

    viewController.loadViewIfNeeded()
    

    Docs: https://developer.apple.com/reference/uikit/uiviewcontroller/1621446-loadviewifneeded

    0 讨论(0)
  • 2021-01-07 23:24

    I agree that forcing a view to load should be avoided but I ran into a case where it seemed the only reasonable solution to a problem (popping a UINavigationController containing a UISearchController that had yet to be invoked causes a nasty console says warning).

    What I did was use new iOS9 API loadViewIfNeeded and for pre-iOS9 used viewController.view.alpha = 1.0. Of course a good comment above this code will prevent you (or someone else) removing this code later thinking it is unneeded.

    The fact that Apple is now providing this API signals it can be needed from time to time.

    0 讨论(0)
  • 2021-01-07 23:30

    Not sure how much cleaner this way, but it still works fine:

    _ = vc.view
    

    UPD: for your convenience, you can declare extension like below:

    extension UIViewController {
        func preloadView() {
            let _ = view
        }
    }
    

    You can read explaination by following URL: https://www.natashatherobot.com/ios-testing-view-controllers-swift/

    0 讨论(0)
  • 2021-01-07 23:32

    merged Rudolph/Swany answers for pre ios9 deployment targets

        if #available(iOS 9.0, *) {
            loadViewIfNeeded()
        }
        else {
            // _ = self.view works but some Swift compiler genius could optimize what seems like a noop out
            // hence this perversion from this recipe http://stackoverflow.com/questions/17279604/clean-way-to-force-view-to-load-subviews-early
            view.alpha = 1
        }
    
    0 讨论(0)
  • 2021-01-07 23:32

    If I understand you correctly, I think there's another fairly standard solution: move the outlet modification/configuration code into a viewDidLoad method (of the recently instantiated VC).

    The topic is also discussed in this question.

    It would require some restructuring, but it might give you a "cleaner" design in terms of MVC if your incoming VC handled its own configuration, and it would avoid the "You should never call this method directly" stricture on loadView.

    0 讨论(0)
  • 2021-01-07 23:33

    You can call [myViewController loadView] to explicitly load the view, instead of abusing the .view getter. The .view getter actually calls loadView if necessary when called.

    It's still not a very nice solution, since the UIView Documentation's section on loadView explicitly instructs that

    You should never call this method directly

    0 讨论(0)
提交回复
热议问题