干净的方式强制视图提前加载子视图

时间:2013-06-24 15:45:46

标签: ios uiview uiviewcontroller

最近我写了一些代码,我尝试引用UIViewController上的插座我刚刚用[storyboard instantiateViewControllerWithIdentifier]实例化,并修改插座在显示{{1}之前指向的子视图}。它没有用,因为ViewController的视图还没有加载它的子视图,包括我的出口所引用的那个,所以属性只给了我一个空指针。

在(通过一些努力)在调试器中跟踪我的问题的原因后,我用Google搜索并通过this one之类的答案了解到,我可以使视图加载其子视图而不通过调用显示ViewController吸气剂。在那之后,我可以毫无问题地访问我的插座。

但这是一个明显的黑客攻击,Xcode - 非常正确 - 不喜欢它,并愤怒地抗议这个警告:

  

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

是否有一种非hacky替代方法可以做到这一点,而不涉及滥用myViewController.view吸气剂?或者,是否存在针对此场景的规范/惯用模式,包括在加载子视图时动态添加要调用的处理程序等内容?

或者标准解决方案只是用.view取代myViewController.view来关闭Xcode的警告,然后与黑客一起生活?

6 个答案:

答案 0 :(得分:37)

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

CREATE TABLE joom.b7gdj_eventmanagement_attachments SELECT * FROM joomla.z3djq_eventmanagement_attachments;
CREATE TABLE joom.b7gdj_eventmanagement_events SELECT * FROM joomla.z3djq_eventmanagement_events;

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

答案 1 :(得分:6)

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

我所做的是使用新的iOS9 API loadViewIfNeeded,而对于iOS9之前使用的是viewController.view.alpha = 1.0。当然,在此代码之上的一个好评论将阻止您(或其他人)在以后认为不需要时删除此代码。

Apple现在提供此API信号的事实可能会不时需要。

答案 2 :(得分: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
    }

答案 3 :(得分:2)

不确定采用这种方式清洁多少,但效果仍然不错:

_ = vc.view

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

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

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

答案 4 :(得分:1)

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

此主题也在此question中进行了讨论。

这需要一些重组,但它可能会给你一个更清洁的"根据MVC进行设计,如果你的传入VC处理它自己的配置,它会避免"你永远不应该直接调用这个方法"对loadView的限制。

答案 5 :(得分:-1)

您可以致电[myViewController loadView]来明确加载视图,而不是滥用.view getter。如果需要,.view getter实际上会调用loadView

它仍然不是一个非常好的解决方案,因为loadView上的{{1}}部分明确指示

  

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