【问题标题】:IOS Navigation Non HeiarchicalIOS导航非分层
【发布时间】:2012-06-06 01:06:05
【问题描述】:

我有一个使用 iOS 5 和 Xcode 4.3.2 的 iOS 应用程序,它由 7 个视图控制器组成。 VC1 链接到 VC2,VC2 可以链接到 VC3-VC7,并且这些控制器中的每一个都可以相互链接(将其视为侧边栏导航)。如果我使用 segues,视图会重复添加到堆栈中,并且如果用户来回移动它可能会使用大量内存。如何在释放前一个控制器的地方实现此导航?它们都是小型控制器,因此加载它们需要很少的时间/处理器/内存。我可以先presentViewController,然后以某种方式释放presentingViewController吗?谢谢。

【问题讨论】:

    标签: ios navigation segue


    【解决方案1】:

    如果你实现了一个 UINavigationController,你可以使用 push 和 pop 视图控制器方法来回切换。此处描述了popToViewController:animated:,以及其他 3 种有用的方法。

    【讨论】:

    • 如果我使用导航控制器来推送和弹出视图,程序流程中不会有“重定向”的感觉。例如从 VC2 进入,我将 VC4 推入堆栈。用户现在想要转到 VC6,所以我弹出 VC4(非动画)并推送 VC6(动画)。当我在 VC6 被推送和显示之前弹出 VC4 时,会不会还有 VC2 的“闪光”?我可以使用导航控制器获得交叉溶解效果吗?
    • 在这种情况下,您可以先推送视图,然后通过直接编辑导航控制器的viewControllers 属性进行更新(removeObjectAtIndex)
    • 实施了这个解决方案来管理堆栈避免重复。控制应用程序的实际内存使用情况。谢谢。我会投票,但还没有足够的声誉。
    【解决方案2】:

    嗯,从 VC1 到 VC2 似乎应该没有问题。对于 VC3 - VC7,您可以:

    • 呈现为 modalViewController 而不是将其推送到堆栈。

    或者: - 如果控制器已经存在于控制器堆栈中,则使用 UINavigationController 的 popToViewController:animated: 函数,否则推送它。喜欢

    // Assuming u need to push VC6
    for(UIViewController *controller in [urNavController viewControllers]){
            if([controller isKindOfClass:[VC6 class]])
            {
               [urNavController popToViewController:controller animated:YES];
            }
            else{
                VC6 *VC6controller = [[VC6 alloc] init];
               [urNavController pushViewController:VC6controller];
            }
    
    }
    

    【讨论】:

    • 我最初将视图呈现为模态,但我的理解是它们被推送到堆栈上,然后当您想要返回时,父(或现在呈现)视图控制器会关闭该视图。在我的情况下,从 VC2 输入用户可以转到 VC4 并从那里转到 VC6 而无需返回 VC2。这不会建立堆栈吗?您的导航控制器选项看起来很有趣。有没有一种快速的方法可以将导航控制器添加到我的应用程序而不用重新构建它,可能来自应用程序委托?我正在使用故事板和 ARC BTW。
    • 好吧,如果我完全明白你的“有没有一种快速的方法可以在我的应用程序中添加导航控制器而不重建它”,但我要做的是首先创建 UINavigationController 的子类,例如我的导航控制器。在 myNavController 中,只需覆盖 pushViewController:animated: 函数并在其中添加上面编写的代码。在此之后,您唯一要做的就是将您在应用程序中使用的当前导航控制器设置为 myNavController,您可以轻松测试代码是否有效,而无需更改应用程序上的任何其他内容。 ;P 希望对您有所帮助。
    • 我当前的应用程序没有使用导航控制器。通过从我的根视图中选择 Editor-> Embed In -> Navigation Controller,我能够通过故事板快速添加一个。对于其他可能不知道的人来说,这更多。我接受了另一个答案,因为它让我能够真正控制堆栈,这个解决方案将允许所有 VC 加载一次(这比我原来的实现要好得多)。
    【解决方案3】:

    您可以使用UINavigationController- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated 方法删除最上面的视图控制器下方的所有视图控制器。由于导航控制器的viewControllers 数组是不可变的,因此您不能直接在viewControllers 数组上使用任何NSMutableArrayremoveObject... 方法。您必须将mutableCopy 制作成一个可变数组,从可变数组中删除您希望丢弃的任何(隐藏)视图控制器,并将生成的精简视图控制器堆栈传递给上述方法。由于您的最顶层视图控制器将保持不变,因此在您的情况下不会有过渡动画(请参阅下面的讨论),因此您也可以直接设置 viewControllers 属性而无需使用 animated: 参数。

    来自 Apple 的文档:

    讨论 您可以使用此方法更新或替换当前视图控制器堆栈,而无需显式推送或弹出每个控制器。此外,此方法允许您更新控制器集而无需为更改设置动画,这可能适合在启动时将导航控制器返回到以前的状态。

    如果启用了动画,此方法会根据 items 数组中的最后一项是否已经在导航堆栈中来决定执行哪种类型的转换。如果视图控制器当前在堆栈中,但不是最顶部的项目,则此方法使用弹出过渡;如果它是最顶层的项目,则不执行转换。如果视图控制器不在堆栈上,则此方法使用推送转换。只执行了一次转换,但当该转换完成时,堆栈的全部内容将被新的视图控制器替换。例如,如果控制器 A、B 和 C 在堆栈上,并且您设置了控制器 D、A 和 B,则此方法使用弹出转换,并且生成的堆栈包含控制器 D、A 和 B。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      相关资源
      最近更新 更多