2

I have a Tab bar Controller (with a bottom menu) and also a top menu. The problem is that I don't want to link the yellow and green views to the tab bar (because the user is going to change the views using the top menu rather than the bottom menu).

I'm having a problem that every time I click the buttons a new instance of the view is going to stack (so I end up having something like V1 -> V2 -> V3 -> V2 -> V4 and so on)

My partial solution is to make something like this:

@IBAction func yellowViewButtonAction(_ sender: AnyObject)
{
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewController(withIdentifier: "YelloViewController") as! YelloViewController

    if let viewControllers = navigationController?.viewControllers {
        for viewController in viewControllers {
            // some process
            if viewController is YelloViewController {
                print("View is on stack")
            }
        } 

         let storyboard = UIStoryboard(name: "Main", bundle: nil)
         let controller = storyboard.instantiateViewController(withIdentifier: "YelloViewController") as! YelloViewController
         self.navigationController?.pushViewController(controller, animated: false)
    }
}

I can see that the view is on navigation stack because the if statement inside the for is true. The question is, how can I retrieve it instead of pushing a new instance of the same view? (Because besides the huge memory problem that this present I also lose any data I had on the view).

I want to keep everything on the stack intact.

Example:

V1 -> V2 -> V3 -> V4 (current view)

If I go back to V1 from V4 I still want to have V4, V3 and V2 on the navigation controller stack.

Another question is that if this solution is something that Apple might refuse.

I appreciate any help.

enter image description here

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Adrian
  • 315
  • 2
  • 3
  • 17

2 Answers2

1

looks like you don't use and need navigation controller. Whenever you call self.navigationController?.pushViewController(controller, animated: false) a new instance of that controller is on its way to stack.

Ideally you would call popViewController from that view controller where you have navigated. When creating custom behavior of tab bar controller it is quite difficult to get the navigation logic exactly as you planned, at least in my opinion.

In cases like this I usually take care of showing and hiding view controllers manually.

@IBAction func didPressTab(sender: UIButton) {
        let previousIndex = selectedIndex
        selectedIndex = sender.tag
        buttons[previousIndex].selected = false
        let previousVC = viewControllers[previousIndex]
        previousVC.willMoveToParentViewController(nil)
        previousVC.view.removeFromSuperview()
        previousVC.removeFromParentViewController()
        sender.selected = true
        let vc = viewControllers[selectedIndex]
        addChildViewController(vc)
        vc.view.frame = contentView.bounds
        contentView.addSubview(vc.view)
        vc.didMoveToParentViewController(self)

    }

where every 'navigation button' has unique id and calls didPressTab function.

I actually learnt this from this tutorial: https://github.com/codepath/ios_guides/wiki/Creating-a-Custom-Tab-Bar

Maciej Chrzastek
  • 1,380
  • 12
  • 18
  • I do need a Navigation Controller because then when i push the Yellow and Green views i can still see the bottom bar menu. Like i said i want the views to remain intact, if i do pop i'll lose all data on the view. – Adrian Nov 14 '16 at 22:28
  • You don't need navigation controller to see bottom menu bars. Have a look at the tutorial in the link and you will see :) Also the code I've provided only moves views so the 'internal' state of those view controllers stays intact. – Maciej Chrzastek Nov 14 '16 at 22:35
  • What im trying to say is that i don't want a custom bottom menu bars because i already have one. I want to be able to change betweens views that are in the navigation controller stack. – Adrian Nov 15 '16 at 00:26
  • That is what I'm trying to say :) use your already existing bottom menu. Whenever you click on menu element I guess some action in your code is executed so just add there the code I posted to switch between view controllers, adjust it a bit for your needs (var names etc) and it should work – Maciej Chrzastek Nov 17 '16 at 13:36
  • Thanks repo. Your idea actually gave me another idea and i ended up using Container View to handle all my views. But thanks for the idea. – Adrian Nov 22 '16 at 15:51
  • Glad I could help :) – Maciej Chrzastek Nov 22 '16 at 20:39
0

Pops view controllers until the specified view controller is at the top of the navigation stack.

Reference - https://developer.apple.com/documentation/uikit/uinavigationcontroller

func popToViewController(UIViewController, animated: Bool) -> [UIViewController]?
IvanPavliuk
  • 1,460
  • 1
  • 21
  • 16