0
votes

Given the setup below, I'd like to be able to segue from green to orange. When I do, however, a new instance of orange is created without the tab bar. I'd really like to have the tab bar if possible. I thought instead of using a segue, I'd simply change the selected index to the nav controller and then forward to orange using the code below. But I still don't get the tab bar.

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "orangeView") as! OrangeViewController
self.present(nextViewController, animated:true, completion:nil)

Problem #2 - when orange is on top, I'd like go one screen back in the navigation stack (to blue). That's easy if I got there through the nav controller - I just pop the view. But if I got to orange from green, there doesn't seem to be a way to get to blue. I really thought changing the selected index should work...but it does not.

enter image description here

3
PurpleViewController is the one you are navigating to ?Muhammad Waqas Bhati
Correct - I'd like to go from green to purple.squarehippo10
I have given my answer below which will solve your both issues.Muhammad Waqas Bhati
Sorry for the confusion - while my code shows that purple is the one I'm navigating to, I just realized that my image actually shows it as orange. I will edit the code to match the image...squarehippo10

3 Answers

0
votes

First you have to select first index of TabbarController and then you have to push PurpleViewController onto the navigation controller like given below

It will solve your both issues

  • You will get Tabbar underneath PurpleViewController
  • secondly If you press back button, you will get blueViewController

    tabBarController?.selectedIndex = 0
    
    if let navC = tabBarController?.viewControllers?.first as? UINavigationController {
    
       let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
       let nextViewController = storyBoard.instantiateViewController(withIdentifier: "purpleView") as! PurpleViewController
       navC.pushViewController(nextViewController, animated: true)
    
    }
    

Hope it will help you.

0
votes

As per the statement you have mentioned and code provided, below are the possible scenarios:

Solution 1: You aren't able to get tab bar controller because in your code you are presenting the view controller. Either you will have to send the instance of your tab bar controller while presenting it or use push to view controller.

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "purpleView") as! PurpleViewController
self.pushViewController(nextViewController, animated:true, completion:nil)

But, in order to push to orange view controller from green, your green view controller should be embedded in navigation controller. (Embed your green view controller in navigation controller)

Solution 2: Since you have directly move to orange view controller from green view controller. There is not blue controller in stack in between green and orange view controller, hence, you couldn't pop to blue view controller. Instead, on pressing back from orange view controller switch to 0 index of tab bar controller to move to blue controller.

0
votes

This is just an interesting question which has many points to dig in.

To simplify the situation, if you want present the purple view from green one AND the tabbar is shown, you can define the context for the vc.(The following code is of green VC)

 override func viewDidLoad() {
    super.viewDidLoad()
    self.definesPresentationContext = true
}

As to the purpleViewController, you present it with .currentContext. Thus, the purple only covers the green. not full screen. (The following code is of green VC also)

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        let purple =   self.storyboard?.instantiateViewController(withIdentifier: "purpleView") as! PurpleViewController
        purple?.modalPresentationStyle = .currentContext
        self.present(purple!, animated: true, completion: {
        })
    }


} 

That's the first question. The second one is important as you don't want to present a new purple VC each time. So in navigation vc, you break the segue link between blue and purple vcs first. This will guarantee the orange one is produced from green.

Actually, it is a trick here that you can present same vcs at both tabs.

We can test it in PurpleViewController: (The following code is of purple VC)

   override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

   guard (self.presentingViewController?.tabBarController?.selectedIndex)! == 1 else {return }. 

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    if let nv = self.presentingViewController?.tabBarController?.viewControllers?.first as? UINavigationController{
        nv.pushViewController(self, animated: false)
    }}
}

It's a precise way to present same vc in both tabs. So you can pick it when you really need them.