【问题标题】:Does presentViewController clean up the parent view?presentViewController 是否清理父视图?
【发布时间】:2014-02-02 17:35:59
【问题描述】:

这是我的问题。

我正在创建的应用具有非线性导航。

所以我正在实现自己的后退按钮并进行自己的导航。

但是,我想知道我应该如何呈现下一个视图。

如果我的导航是线性的,我可以这样做:

-(IBAction)btnBackPressed:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

但是这对我不起作用,因为按下返回不一定会让你回到之前的视图。

因此我正在考虑使用例如:

AddTaskViewController *add = [[AddTaskViewController alloc] init];
[self presentViewController:add animated:YES completion:nil];

我不使用 Storyboard 的原因是因为我所有的 UI 都是用代码以编程方式制作的。

对此我担心的是,我认为 presentViewController 只会将新视图推送到堆栈顶部。因此,如果用户向后、向前、向后按,他最终会耗尽内存。

鉴于我需要非线性导航并且我的所有 UI 都是在代码中创建的,我应该使用什么来呈现下一个视图而不浪费内存?

谢谢

【问题讨论】:

  • 你知道 UINavigationController 有一个名为setViewControllers:animated: 的方法吗?您可以在堆栈中插入或删除视图控制器,从而创建非线性导航系统。如果这对你来说占用了太多内存,你可能需要做很多“自己动手”。
  • @architectpianist 你能举个例子来回答吗?插入新的和删除旧的的例子?我无法想象如何从给定视图访问导航控制器。

标签: ios objective-c


【解决方案1】:

如果您仍然对使用 UINavigationController 的干净解决方案感兴趣,请考虑这种设计。

情况:让 A 和 B 成为视图控制器的类型。 A 是根,B 是详细视图,可以推送或弹出到其他 B 控制器。

目标:我们想要删除任何不与当前呈现的视图控制器相邻的 B 控制器,但保持层次结构,以便我们可以在必要时重新创建视图。因此,导航控制器将知道的最大层次结构是 A--B--B。

设计:让 A 成为导航控制器的代表。给它一个模型对象数组,这些对象代表 B 控制器,足以从它们重新创建视图。每当推送 B 控制器时添加到此数组,A 将从导航控制器委托方法中知道这一点。弹出 B 控制器时从堆栈中删除对象。

在推送 B 控制器时,A 控制器将获取导航控制器的视图控制器堆栈,并且(如果存在)直接在推送之前显示的控制器之前移除 B 控制器。在弹出 B 控制器时,A 控制器将(如果存在)直接在目标控制器之前重新创建 B 控制器并将其插入堆栈。

示例:假设 A 一直在跟踪这样的层次结构:A--B1--B2--B3--B4。通过上述系统,导航控制器只知道 A--B3--B4。当用户弹出 B4 时,将通知 A 控制器并重新创建 B2,将其插入到 B3 之前。因此,新的层次结构是 A--B2--B3。当 B5 从 B3 被推入时,B2 被移除以产生 A--B3--B5。

我意识到这是一个实施起来相当复杂的系统,所以如果您有大量控制器并且需要UINavigationController 的便利设施,我只会推荐它。我想到的另一个解决方案是UIPageViewController,它允许您即时提供视图控制器。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    是的,如果你继续使用模态视图控制器,用户最终会耗尽内存是正确的

    [self presentViewController:add animated:YES completion:nil];
    

    [self dismissViewControllerAnimated:YES completion:nil];
    

    只会关闭正在显示的最顶层的 viewController。

    相反,您最好构建自己的容器视图控制器并处理自己的导航。有关更多信息,请阅读 UIViewController Apple 文档中的“实现容器视图控制器”部分。 https://developer.apple.com/library/ios/Documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html

    【讨论】:

    • 无论如何这可以通过导航控制器来完成?我基本上需要的是,在任何给定时间,堆栈中总是有 1 个视图。
    • 我可以弹出旧的 [self.navigationController popViewControllerAnimated:YES];并推新?
    • popToViewController 似乎可以做到。
    • popToViewController 可以工作,但它要求 viewController 已经在堆栈中。
    • -(void) showNextView:(UIViewController*)newController { [self.navigationController pushViewController:newController animated:true]; [self.navigationController popToViewController:newController Animation:false]; }
    猜你喜欢
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    相关资源
    最近更新 更多