Why tab bar is missing after presenting a new view controller?
Asked Answered
S

4

7

I have created a simple tab bar with three views in storyboard. The tab bar works well, but when I try to show another view controller from a button within a tab, the new view is placed over the whole screen and also over the tab bar.

This is how I present the view so far when a button is pressed:

@IBAction func buttonPressed(_ sender: UIButton) {
    let newVC = self.storyboard?.instantiateViewController(withIdentifier: "extraVC")
    self.present(newVC!, animated: true, completion: nil)
}

The other idea I had was this:

self.tabBarController?.present(vc!, animated: true, completion: nil)

But this didn't work either.

So how can I present another view controller within the tab bar (so that the bottom bar is still shown)?

Spectrum answered 25/10, 2017 at 18:45 Comment(0)
S
32

When you present a view controller modally, its presentation style will be "Full Screen" by default. What you want to do is have it do in this case is just cover part of the screen (the part where the presenting view controller is drawn.

One way to accomplish this is to:

  1. Set the modalPresentationStyle for the presented view controller to be .currentContext or .overCurrentContext

  2. In the view controller that will be presenting the modal, set its definesContext property to true.

These steps can be done either in Interface Builder by setting attributes on the segue and the view controller, or you can modify your code to include the following:

@IBAction func buttonPressed(_ sender: UIButton) {
    let newVC = self.storyboard?.instantiateViewController(withIdentifier: "extraVC")
    self.definesPresentationContext = true
    newVC?.modalPresentationStyle = .overCurrentContext
    self.present(newVC!, animated: true, completion: nil)
}

What this combination of properties does is:

  1. Indicate for the presented view controller that you want it to be presented in a non-full screen context (some specific section of the screen)

  2. Indicate that the presenting view controller is in the section of the screen / the context you want the modal to be drawn according to.

More details can be found in the Apple Documentation

Solute answered 15/3, 2018 at 4:20 Comment(1)
10 out of 10 answer.Weis
S
1

When you are using present method, the ViewController is presented modally and covers your UITabBarConntroller. Instead of showing your view modally you can embed every first view controller in your TabBar into UINavigationController and then use method pushViewController to push it onto stack. You will have your TabBar visible and nice looking animation for free.

Salpingectomy answered 25/10, 2017 at 18:49 Comment(4)
I tried to embed every view into a navigation controller and you are right this works well with the tab bar, but then the tab bar icons are missing. And because I did not find a solution for that problem I thought not to use a nav controller. Do you have any idea why the icons are missing with a nav controller?Spectrum
The icons are missing because UITabBarController is getting them from the first view controller that is embedded inside every tab. The first controller is now UINavigationController and be default UINavigation controller doesn't have icon. You have to provide it in the storyboard or in code.Kasiekask
So what you are saying is that I would have add the tab bar icon for each view controller in code now? I suppose I cannot simply add this in viewDidLoad?Spectrum
If you don't want to use storyboards you have to do this before viewDidLoad being called. Create your subclass of UITabBarController and setup your view controllers there. Before adding your view controllers to UITabBarController property give them an icon.Kasiekask
M
0

In Xcode, I created a new project using the Tabbed App template to illustrate the solution above. This will create a project with a tabbar controller and two view controllers. I added a button with the title "view page" to the first view controller and embedded a navigation controller from the storyboard.

enter image description here

The storyboard will look like this after making the above changes:

enter image description here

In the FirstViewController.swift file, I created an IBAction for the button with the following code that will create another view controller called DetailViewController, with the title Favorites and a background color of orange. I used the navigation controller to present it by pushing it onto the navigation controller stack.

@IBAction func viewPageButtonTapped(_ sender: UIButton) {
    print("viewPageButtonTapped")
            let pinkViewController = DetailViewController()
    pinkViewController.title = "Favorites"
    pinkViewController.view.backgroundColor = UIColor.orange
    navigationController?.pushViewController(pinkViewController, animated: true)
}

When I run the project on the simulator, I got the desired result. Hope this helps give you some ideas.

Marentic answered 15/3, 2018 at 3:48 Comment(0)
L
-2

In your viewController do:

self.tabBarController?.present(nextViewController, animated: true/false, completion: {})
Ladino answered 25/10, 2017 at 19:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.