Adding custom view above tab bar controller/navigation controller?

27,294

Solution 1

There isn't really any good way to do this. The various subviews of UINavigationController and UITabBarController are both private, and trying to mess with them is likely to not work correctly. And Apple doesn't give us the tools to create "container" view controllers, so you can't easily embed the UINavigationController/UITabBarController inside another view controller or recreate UINavigationController/UITabBarController yourself.

Your best bet is probably to go ahead and try to create your own "container" view controller, and deal with some things not working right. In particular, the contained view controller's parentViewController will return nil, and therefore various other things on the contained view controller or its sub-controllers will be broken (e.g. the interfaceOrientation property will be wrong, presentModalViewController:animated: might not work right). Other things may be broken too.

Or you could wait until some future version of iOS actually has support for us to create container view controllers (if ever), and then support only that version and up.

Solution 2

Add the view to the tabBarController View itself:

[self.tabBarController.view addSubview:yourView];

Solution 3

You could simple addSubview to window:

[self.view.window addSubview:myView];

Solution 4

I had the same problem and ended up doing something like this:

newView.frame = tabBarController.tabBar.frame
tabBarController.view.addSubview(newView)

Adding the view to the tabBarController and using the frame of the current tabbar as the position of the new view did the trick.

Solution 5

For those who are looking to add a view, or in my case an indicator view over the tab bar view, here is the code snipet on GitHub with very easy implementation.

Preview

enter image description here

Github gist

https://gist.github.com/egzonpllana/cc5538f388d8a530e7c393e7344e57a5

Share:
27,294
xil3
Author by

xil3

Open source PHP / Java (J2ME/Android) / Objective-C (iPhone/iPad) Developer

Updated on July 09, 2022

Comments

  • xil3
    xil3 almost 2 years

    I tried the following code, in an attempt to get the custom view displaying above the tab bar controller (which happens to have a navigation controller within all of it's tabs).

    The problem is that it overlays on top of the navigation bar, and I want the navigation bar to be moved down.

    I tried setting the frame of the tab bar controller, but that didn't move it at all.

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {    
        // Override point for customization after application launch.
        // Add the tab bar controller's current view as a subview of the window
        //self.tabBarController.view.frame = CGRectMake(0, 62, 320, 320);
        self.window.rootViewController = self.tabBarController;
    
        [self.window makeKeyAndVisible];
    
        // setting up the header view
        self.headerView = [[HeaderView alloc] initWithFrame:CGRectMake(0, 20, 320, 42)];
        [self.window addSubview:self.headerView];
    
        // setting up facebook stuff
        AgentSingleton *agentSingleton = [AgentSingleton sharedSingleton];
        agentSingleton.facebook = [[Facebook alloc] initWithAppId:APP_ID];
    
        return YES;
    }
    

    Any ideas?

  • xil3
    xil3 almost 13 years
    Vertically above the rest of the content.
  • xil3
    xil3 almost 13 years
    I got it placed at the top, but at the moment it's covering the navigation controller. I need to push down the tab bar controller somehow...
  • dwbrito
    dwbrito almost 13 years
    Use a modalViewController on which the background view is the topmost view on the current view controller (something like view.superview.superview.superview until its nil)
  • lewis
    lewis over 10 years
    For me, self.view.window was null so adding a subview has no effect.
  • Leo Dabus
    Leo Dabus over 6 years
    @Lewis42 Not saying that this is the correct approach but inside viewDidLoad method window property will always be nil. This need to be done inside viewDidAppear method.
  • Cheng Yang Chen
    Cheng Yang Chen over 4 years
    You saved my day!
  • infinity_coding7
    infinity_coding7 over 4 years
    Thanks, Xcode 11.2.1 iOS 13.1 still works, the slight change is the first line, the newly added view could cover the full screen (including the tab bar) self.newView.frame = self.tabBarController?.view.frame ?? CGRect.zero
  • ShadeToD
    ShadeToD over 3 years
    Could you show how did u add this IndicatorView to the UITabBarController? Should I use default addSubview method on that controller? I found one issue with that use case. When you push new viewController then this view will disappear when u will go back to the main tabbarcontroller.
  • Egzon P.
    Egzon P. over 3 years
    Hi ShadeToD, did you tried the way I have suggested, it's working fine for me. See github link at the "// How to use"
  • ShadeToD
    ShadeToD over 3 years
    Yes I have tried your code and there is issue with this added view when you hide tabbar or when hidesBottomBarWhenPushed is set to true.
  • Egzon P.
    Egzon P. over 3 years
    Yes, that can happen.. A quick solution would be to add/remove the tabBar indicator view on viewWillAppear/viewWillDissapper.