ViewController 转换

Posted

技术标签:

【中文标题】ViewController 转换【英文标题】:ViewController transitions 【发布时间】:2014-05-08 07:41:25 【问题描述】:

我正在构建一个使用大量网络服务的 ios 应用。 该应用程序有一个 UItabBarController 作为它的根 VC。

在我的一个控制器中,我将 viewController 推送到 UINavigationController 上。我推入堆栈的 ViewController 是一个 UITableViewController,它有一个 UITableView 和来自网络的数据。我在用户在数据中下降的每个级别上重新启用控制器。然后,在最后一级,我调用了一个 Web 服务,然后希望整个 UITableViewController 被解除并显示原始视图控制器。

看起来是这样的:

ViewControllerA (UIViewController) -> 用户点击一个按钮 - 将ViewControllerB 推到它上面。 (UINavigationController)。

完成 ViewControllerB 后,我需要将其关闭,并显示 ViewControllerA 和结果。

在 ViewControllerB 中,我在 NSNotification 方法中做了这样的事情:

if ([errorString hasPrefix:@"No descendants"])
    UINavigationController *navigationController = 
                     [self.tabBarController.viewControllers objectAtIndex:1];
    BBSearchViewController *searchViewController = 
                     navigationController.viewControllers[0];
    searchViewController.categoryId = self.categoryId;


    if (searchViewController.brwosingCategoriesFromSearchPage)
        [[BBDataStore sharedDataStore]deRegisterForNotifications:self];
        [self.navigationController popToRootViewControllerAnimated:NO];

这会导致控制台出现此错误:

> 2014-05-08 09:32:16.306 TestApp[36948:60b] Finishing up a navigation transition 
in an unexpected state. Navigation Bar subview tree might get corrupted.

 2014-05-08 09:32:16.780 TestApp[36948:60b] Unbalanced calls to begin/end 
appearance transitions for <ViewControllerA: 0xd08aa00>.

谁能告诉我我在这里做错了什么?

【问题讨论】:

您是否在每次单击表格单元格时创建UITableViewController 的新实例?为什么不只是重新加载表数据并使用一个控制器? 是的,我在每次单击单元格时创建一个新实例。我不想重新加载数据,因为用户需要能够备份链。所以,第 1 级 -> 第 2 级 - 第 3 级。然后,如果他们愿意,可以回到第 2 级或第 1 级。你认为这是我的问题的原因吗? 只用一个视图控制器试试。当用户单击单元格时,获取下一级数据并重新加载表。还要跟踪堆栈中的当前级别。当单击后退按钮时,从堆栈中弹出。堆栈为空,然后弹出表格视图控制器,否则您需要显示上一级的数据。 用户可以通过数以百计的关卡。数据集相当大。不过我会试试的。谢谢。 那么最好只保留一个 ViewController。这样更容易处理。 【参考方案1】:

您收到这些错误是因为您在完成另一个转换之前尝试了一个转换。在您的情况下,您似乎在视图完成出现之前收到通知,然后尝试弹出到根目录。您应该使用用户输入(当用户点击按钮时)或至少在viewDidAppear: 之后调用popToRootViewControllerAnimated:

【讨论】:

当我从 Web 服务返回数据时会调用通知。它不是由用户触发的。在此通知之后,我需要关闭 viewControllerB 并显示 viewControllerA 的结果。我还应该在哪里使用 popToRootViewController? 看起来您在视图完成呈现之前收到了通知。如果您真的想这样做,您应该在转换完成后向 Web 服务询问信息。在viewDidAppear 中注册通知将完成此操作。但是在某些情况下你会产生的效果是你的视图在它出现后立即被关闭——这是你想要的效果吗? 我不确定我是否理解正确。让我详细说明一下。我在 viewControllerB 上的 viewWillAppear 中注册查看通知。我收到两个通知。一个告诉我 web 服务启动了另一个告诉我它完成了。当我在 viewControllerB 上收到第二个 Web 服务通知时 - 我检查结果,如果 viewControllerB 中没有其他内容可显示 - 我希望 viewControllerB 被关闭并出现 viewControllerA - 这将根据数据执行新的 Web 服务调用来自 viewControllerB。感谢您的帮助! 您是否尝试在viewDidAppear 而不是viewWillAppear 中注册通知? viewWillAppear 中的转换尚未完成,您会在注册后立即收到第二条通知。 是的。在 viewDidApear 中,它破坏了应用程序的流程。我可以加载 viewControllerB 的一个实例 - 进入下一个级别意味着我无法再获取数据并且它仍然是空的(即 UITableView)

以上是关于ViewController 转换的主要内容,如果未能解决你的问题,请参考以下文章

如何有返回按钮才能返回到第一个 ViewController?

无法使用 mapKit 从 ViewController 将坐标发送到具有委托的另一个 viewController

向 UINavigationBar 添加搜索按钮:Swift

使用来自其他 viewController 的 Alamofire 从 JSON 中取出 HTML 标签

故事板连续和返回

关于 UIViewController 层次结构和流程的建议