导航控制器循环

时间:2017-11-13 21:04:16

标签: ios uiviewcontroller

enter image description here

我正在制作一款具有购物车功能的应用。购物车VC可通过导航栏上的按钮从多个VC访问。到目前为止,我只有一个导航控制器,如图所示,每个VC都带我到下一个,没什么特别的。第3个VC(指向蓝色箭头)是一个VC,显示产品/项目的详细信息,并允许我将其添加到购物车。

购物车VC出现问题。要编辑该项目,我想重复使用之前使用的相同产品/项目的详细信息(指向蓝色箭头)。

现在,我确实没有问题,但我注意到,一旦我创建了蓝色segue,第3个VC的导航栏就在Storyboard中消失了但是当我跑的时候我仍然可以看到它该应用程序。

注意:

  1. 图片中的所有段落都是"显示"
  2. 购物车VC没有像其他3那样显示自己的按钮。所以从技术上来说,我阻止了购物车VC的无限/循环 - 产品/项目细节VC相互显示。
  3. 我的问题是:

    1. 以VC的方式设计应用程序到另一个VC并且其他VC可以返回到第一个VC是不对的?我是否会在未来遇到问题,或许是内存泄漏?
    2. 有没有更好的方法来实现我想要实现的目标?
    3. 如果有人需要进一步解释,请告诉我,我会编辑我的问题。

      编辑:为了澄清,蓝色segue基本上是购物车VC中UITableView中的一个按钮。如果您点击该按钮,它应该打开产品/项目详细信息VC,并允许您编辑项目的颜色等。在项目详细信息VC中,而不是将项目作为新项目添加到购物车,我&# 39; d显示一个编辑按钮,可以将编辑请求发送到API并将VC关闭回购物车,或者我可以使用导航控制器中的后退按钮返回购物车。

      EDIT2:@beshio

      感谢您的回答。然而,VC1实际上是我的根VC,其中所有应用程序都启动。我没有理解为什么从导航控制器的堆栈中移除VC。我希望Back按钮按预期工作。

      到目前为止,我已经达到了我想要的水平,但我担心让两个VC相互隔离会导致问题。我已经在VC3中禁用了Cart按钮,以防VC3从Cart中出现,因此可以防止循环。我只担心任何内存泄漏。

2 个答案:

答案 0 :(得分:2)

有可能实现这种转变。

在这里,我将介绍如何使用您的图表实现此功能。 如图所示,假设您有VC1,VC2,VC3(从上到下)和VCX(带蓝色框)。您需要定义过渡和关联的动画方向(按下:从右到左或从左到右)。如图所示,如果您将过渡和动画定义为:

  1. VC1到:VC2(推送),VCX(推送)
  2. VC2到:VC3(推送),VCX(推送)
  3. VC3 to:VCX(推送)
  4. VCX to:VC3(pop)
  5. 并假设我们已经实例化了所有视图控制器,然后,

    • VC1到VC2过渡

    在VC1:

    navigationController!.pushViewController(VC2, animated: true)
    

    在VC2:

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // remove VC1 from navigation stack (I assume VC1 is not a root VC)
        let allControllers = NSMutableArray(array: navigationController!.viewControllers)
        allControllers.removeObject(at: allControllers.count - 2)
        navigationController!.setViewControllers(allControllers as [AnyObject] as! [UIViewController], animated: false)
     }
    
    • VC1到VCX过渡

    在VC1:

    navigationController!.pushViewController(VCX, animated: true)
    

    在VCX:(A)

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let allControllers = NSMutableArray(array: navigationController!.viewControllers)
        if (navigationController!.viewControllers[allControllers.count-2] != VC3) {
            // if not from VC3, remove VC from stack and put VC3
            allControllers.removeObject(at: allControllers.count - 2)
            allControllers.insert(VC3, at: allControllers.count - 1)
            navigationController!.setViewControllers(allControllers as [AnyObject] as! [UIViewController], animated: false)
        }
    
    • VC2到VC3过渡

    在VC2:

    navigationController!.pushViewController(VC3, animated: true)
    

    在VC3:(B)

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let allControllers = NSMutableArray(array: navigationController!.viewControllers)
        if (navigationController!.viewControllers[allControllers.count-2] == VC2) {
            // if from VC2, remove it
            allControllers.removeObject(at: allControllers.count - 2)
            navigationController!.setViewControllers(allControllers as [AnyObject] as! [UIViewController], animated: false)
        }
    }
    
    • VC2转换为VCX

    在VC2:

    navigationController!.pushViewController(VCX, animated: true)
    

    在VCX:与(A)

    相同
    • VCX转换为VC3

    在VCX:

    navigationController!.popViewController(animated: true)
    

    在VC3:与(B)

    相同

    注意当用户滑动(从左到右)返回并在途中取消(==向左滑动)时,会调用viewDidAppear。因此,您需要在viewDidAppear处针对该情况使用更多小代码。

    如果你想要不同的动画方向,通过操纵堆栈和使用push / pop,你可以轻松实现它。 This解释了如何。

答案 1 :(得分:0)

真棒。

在这些场景中,当您循环堆叠许多控制器时,应使用setViewControllers([UIViewController], animated: Bool)在堆栈中获取所需的viewcontrollers。

其他方式是你编写自己的类来自UINavigationController方法,pushToCheckout(animated:Bool), popToEditCart(animated:Bool) , removeIntermediateControllers()