18

最近我写了一些代码,我试图引用一个UIViewController我刚刚实例化[storyboard instantiateViewControllerWithIdentifier]的插座,并在呈现ViewController. 它不起作用,因为ViewController' 的视图尚未加载其子视图,包括我的插座所引用的子视图,因此该属性只给了我一个空指针。

在(经过一番努力)在调试器中跟踪我的问题的原因之后,我四处搜索并通过类似这样myViewController.view的答案了解到,我可以通过调用getter使视图加载其子视图而不显示。之后,我可以毫无问题地访问我的插座。

不过,这是一个明显的 hack,并且 Xcode - 非常正确 - 不喜欢它,并且愤怒地抗议这个警告:

未使用的属性访问结果 - 不应将 getter 用于副作用

有没有一种不涉及滥用.view吸气剂的非hacky替代方法?或者,这种场景是否存在规范/惯用模式,涉及动态添加处理程序以在加载子视图后立即调用?

还是标准解决方案只是替换myViewController.view[myViewController view]关闭 Xcode 的警告,然后接受黑客攻击?

4

6 回答 6

42

在 iOS 9 或更高版本上,可以使用:

viewController.loadViewIfNeeded()

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

于 2016-07-21T07:51:11.877 回答
6

我同意应该避免强制加载视图,但我遇到了一个情况,它似乎是解决问题的唯一合理解决方案(弹出一个包含尚未调用的 UISearchController 的 UINavigationController 会导致令人讨厌的控制台显示警告)。

我所做的是使用新的 iOS9 API loadViewIfNeeded 并且对于 pre-iOS9 使用 viewController.view.alpha = 1.0。当然,此代码上方的良好注释将阻止您(或其他人)稍后删除此代码,认为它是不需要的。

Apple 现在提供此 API 的事实表明它可能不时需要。

于 2015-10-14T12:56:21.610 回答
3

不确定这种方式有多清洁,但它仍然可以正常工作:

_ = vc.view

UPD:为方便起见,您可以声明扩展名,如下所示:

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

您可以通过以下 URL 阅读说明:https ://www.natashatherobot.com/ios-testing-view-controllers-swift/

于 2018-09-17T16:31:21.030 回答
2

ios9 前部署目标的合并 Rudolph/Swany 答案

    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
    }
于 2016-10-04T14:39:09.450 回答
1

如果我理解正确,我认为还有另一个相当标准的解决方案:将插座修改/配置代码移动到viewDidLoad(最近实例化的 VC 的)方法中。

这个问题也讨论了这个话题。

这将需要一些重组,但如果您的传入 VC 处理自己的配置,它可能会为您提供 MVC 方面的“更清洁”设计,并且它将避免“你不应该直接调用此方法”的限制loadView

于 2013-08-11T13:22:12.407 回答
-2

您可以调用[myViewController loadView]以显式加载视图,而不是滥用.viewgetter。如果需要,.viewgetter 会在调用loadView时实际调用。

它仍然不是一个很好的解决方案,因为UIView 文档的部分loadView明确指示

你不应该直接调用这个方法

于 2013-06-24T16:12:22.097 回答