iOS开发:如何在将视图控制器推入导航堆栈之前预先加载视图控制器?

时间:2010-12-19 18:19:43

标签: iphone ipad ios adwhirl

我正在深入iOS开发,我正在构建一个益智游戏,以帮助我熟悉该平台。我有AdWhirl在用户完成拼图时显示的分数屏幕中显示广告。问题是,分数屏幕视图控制器至少需要几秒钟来请求和接收广告,在此时用户查看分数并移动到不同的视图。我计划在用户解决谜题时实现动画,动画完成所需的时间是请求和接收将在下一个(得分)视图中显示的广告的好时机也将被采取。

在解谜动画正在进行的过程中,当我将视图控制器推到导航堆栈时,如何预加载下一个视图控制器以便广告存在?如果这是不可能的,或者这是一个坏主意,您对动画发生时我如何请求和接收广告有任何建议吗?

非常感谢您的智慧!

注意:对于那些不熟悉AdWhirl的人来说,请求和接收广告的过程很简单。在视频控制器的viewDidLoad方法中,您希望广告显示在其中,您创建AdWhirlView(UIView的子类),将其添加为子视图,并调用请求广告的方法。广告到达时,会调用委托方法将其显示在父视图中。

6 个答案:

答案 0 :(得分:30)

只有使用[viewController loadView] 的副作用,那就是在加载视图后不会自动调用viewDidLoad。

要正确执行并确保调用viewDidLoad,而不是自己调用loadView,您可以使用

实例化UIViewController的视图
  UIView *view = myViewController.view;

  UIView *view = [myViewController view];

这将调用loadView(如果视图尚未加载),然后在视图加载完成后调用viewDidLoad。

答案 1 :(得分:14)

响应接受的答案,您不得手动调用-loadView。来自documentation

  

你永远不应该直接调用这个方法。视图控制器调用   请求view属性但当前为nil时此方法。   此方法加载或创建视图并将其分配给视图   属性。

相反,您应该调用[myViewController视图],这将触发视图加载。

一如既往,请阅读文档!

答案 2 :(得分:2)

将此信息放在您的代理application:didFinishLaunchingWithOptions:

  dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
                   UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboard" bundle:[NSBundle mainBundle]];
                   [storyboard instantiateViewControllerWithIdentifier: @"TheViewControllerYouWantToPreload"];
                 });

dispatch_async将使整个事物在后台加载。

答案 3 :(得分:0)

在iOS 9中添加了一种新方法loadViewIfNeeded()。我相信它最初是用于视图控制器的单元测试,但它也适用于这种情况。

答案 4 :(得分:0)

iOS 5及更高版本提供两个功能。

  • setNeedsLayout()
  • layoutIfNeeded()

调用setNeedsLayout()就像告诉系统您要更新被调用视图和子视图的布局并重画它们一样。更改不会立即反映出来。正如名称中所包含的那样,它仅设置标记并将其反映在调度中。只有在返回下一个更新周期时,更改才能反映在视图中。

由该方法的调用引起的任务必须异步执行,这一点很重要。因此,开发人员不知道更新周期何时才能反映出更改。

另一方面,layoutIfNeeded()是一个同步呼叫。他们要求系统立即反映更改。顾名思义,布局是立即完成的。因此,通过在调用此方法后返回时间控件,更改已经反映在视图中。

答案 5 :(得分:-4)

您可以手动调用loadView,我不知道是否有任何副作用,但我不这么认为。

感谢Tommy,实际上,访问view属性确保只有在尚未加载视图层次结构时才会有效地调用loadView,如果loadView代码确实注意到它,则避免任何潜在的泄漏。