【问题标题】:ViewWillAppear not getting called in modal controller. What is wrong here?ViewWillAppear 没有在模态控制器中被调用。这里有什么问题?
【发布时间】:2012-06-07 04:11:56
【问题描述】:

我看过几篇关于 ViewWillAppearViewDidAppear 在某些情况下不会触发的文章,但我仍然想知道这种行为背后的想法是什么,以及在我的具体情况下如何解决它。

  • window 有一个视图,由默认的 UIVieController 处理并包含一个按钮。
  • 单击按钮以模态方式显示另一个视图控制器 (VC_MAIN)。
  • 根据设置,模态显示的视图控制器 (VC_MAIN) 将呈现视图 A 或视图 B。
  • 视图 A 和 B 由不同的视图控制器(VC_AVC_B)处理。
  • VC_AVC_B 中未调用任何 ViewWill* 或 ViewDid* 方法。
  • 我可以通过在 VC_MAIN 中相应的 ViewDid* 和 ViewWill* 方法中手动调用它们来解决它。但是,如果 VC_MAIN 决定从 VC_A 切换到 VC_B,这将无济于事。 VC_MAIN's View* 方法不会被再次调用,VC_A'sVC_B's 也不会。

我当然可以在从 A 切换到 B 时关闭 VC_MAIN,但我不想这样做。我想为切换设置动画,而不仅仅是打开另一个模式视图。

为什么不调用这些方法呢?它真的超出了我的范围!如果您查看 UISplitViewController:它包含两个子控制器,可以显示其他控制器。他们基本上做的和我想做的一样。 Apple 是否在代码中添加了杂牌?

【问题讨论】:

  • ViewWillAppear 中的大写 V 是不是拼写错误?该方法名为viewWillAppear:。与所有方法名称一样,它以小写字母开头。
  • 啊,对不起。我正在使用 MonoTouch。我添加了一个标签。但问题在 MT 和 ObjC 中是相同的。

标签: objective-c cocoa-touch ios4 xamarin.ios


【解决方案1】:

我对此类问题的经验:
如果你有一个视图控制器 VC 管理一个主视图 V 并且这个视图有一个由另一个视图控制器 VC 管理的子视图 V' 'viewWillAppear:willRotateToInterfaceOrientation: 等其他方法不会发送到 VC'

您可以手动从 VC 转发这些呼叫:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [mySubViewController viewWillAppear:animated]; // VC'
}

(注意:我对 MonoTouch 不熟悉,所以我用 ObjC 代码回答)

编辑

这提醒了我View Controller Programming Guide 明确指出:

您的每个自定义视图控制器对象 create 负责管理所有 单个视图中的视图 等级制度。 [...] 一对一 视图之间的对应关系 控制器及其视图中的视图 层次结构是关键设计 考虑。你不应该使用 多个自定义视图控制器 管理相同的不同部分 查看层次结构。

【讨论】:

  • 我已经这样做了。问题是,如果我将 mySubViewController 更改为其他内容,则 VC.viewWillAppear 将不会再次被调用(它已经出现)。因此 mySubViewController 的 viewWillAppear: 也不会触发。而且我没有办法解决它,只能改变我的设计。 :-(
  • @Krumelur 是的,我没有看到有效的解决方案,特别是如果这是 Apple 的设计决定(但在某些情况下,我也希望能够嵌套视图控制器)。我在我的回答中包含了文档中的引用...
  • 我猜苹果的观点是视图可能有也可能没有与之关联的视图控制器。每次查找视图都必须遍历所有子视图会浪费时间,因此最好让开发人员根据需要处理它。
  • 但苹果是如何处理它的呢?以 UINavigationController 为例。您将另一个控制器推到它上面,所有视图*都会触发。但正如我们所见,它们不会自动触发。那么苹果的决定是什么?生火还是不生火?这就是我觉得很奇怪的地方。 UINavigationController 完全有几个控制器来管理一个视图层次结构,这与指南所述的完全相反。 UISplitViewController 也是如此。为什么苹果公司对规则做出这样的例外并告诉美国不要这样做?他们是如何解决的?
【解决方案2】:

我猜一个原因是

根据设置,模态显示的视图控制器 (VC_MAIN) 将呈现视图 A 或视图 B。

视图 A 和 B 由不同的视图控制器(VC_A 和 VC_B)处理。

如果您阅读 Apple 的视图控制器编程指南中的介绍,他们建议每个屏幕只使用一个视图控制器,即使它管理多个视图或子视图的层次结构。直接在 VC_MAIN 中管理视图 A 和 B 可能会更好,然后您将获得所需的通知。如果您出于某种原因更喜欢使用单独的视图控制器的方式,您可能必须自己通知它们。

【讨论】:

  • 但这不可能。一个屏幕可能有一个 UISplitViewController,左边有一个 UINavigationController,右边有一个 UIViewController,顶部有一个 UIViewController 以模态方式呈现...
【解决方案3】:

您真的应该手动调用这些方法。它是一种管理和显示 VC 视图的自定义方式,因此由您决定每个子视图控制器何时接收生命周期调用。 在 VC_MAIN 中,创建一个将调用的 showVC:newVc 方法

[newVc viewWillAppear]
[mainView addSubview:newVc.view]
[newVc viewDidAppear]

同样,创建一个 hideVC: 将调用 viewWill/DidHide

在你的VC_Main viewWillAppear上,根据当前配置适当调用showVC方法,每次切换视图时,都会正确调用方法。

这是一个老问题,在 iOS5 上已部分处理,但以这种方式仍然可以正常工作,并且完全向后兼容到 iOS3。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-11
    • 2016-03-24
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 2021-03-30
    相关资源
    最近更新 更多