Change UITabBar height

97,050

Solution 1

I faced this issue and I was able to solve it.

You have to add following code to your subclass of UITabBarController class.

const CGFloat kBarHeight = 80;

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    CGRect tabFrame = self.tabBar.frame; //self.TabBar is IBOutlet of your TabBar
    tabFrame.size.height = kBarHeight;
    tabFrame.origin.y = self.view.frame.size.height - kBarHeight;
    self.tabBar.frame = tabFrame;
}

Swift:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    tabBar.frame.size.height = kBarHeight
    tabBar.frame.origin.y = view.frame.height - kBarHeight
}

Solution 2

Swift3.0, Swift 4.0 compatible

Pre-iPhone X default tab bar height: 49pt

iPhone X default tab bar height: 83pt

A universal solution supporting every iOS device including iPhone X screen size would look like this:

  1. Capture UITabBar's default height:

    fileprivate lazy var defaultTabBarHeight = { tabBar.frame.size.height }()
    
  2. Adjust UITabBar's height:

        override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
    
            let newTabBarHeight = defaultTabBarHeight + 16.0
    
            var newFrame = tabBar.frame
            newFrame.size.height = newTabBarHeight
            newFrame.origin.y = view.frame.size.height - newTabBarHeight
    
            tabBar.frame = newFrame
        }
    

Solution 3

For iOS 8.2, Xcode 6.2 Swift language:

Create a "DNMainTabVC.swift" (DeveloperNameMainTabViewController.swift file) for your UITabBarController (of type UITabBarController) and connect it to your storyboard VC.

Add the following lines:

override func viewWillLayoutSubviews() {
    var tabFrame = self.tabBar.frame
    // - 40 is editable , the default value is 49 px, below lowers the tabbar and above increases the tab bar size
    tabFrame.size.height = 40
    tabFrame.origin.y = self.view.frame.size.height - 40
    self.tabBar.frame = tabFrame
}

This worked for me.

Solution 4

Tested in XCode 9.0 and Swift 4

As suggested in previous answers - inherit UITabBar and override sizeThatFits, but mark height as @IBInspectable, so it could be set in the Interface Builder:

import UIKit

class CustomTabBar : UITabBar {
    @IBInspectable var height: CGFloat = 0.0

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var sizeThatFits = super.sizeThatFits(size)
        if height > 0.0 {
            sizeThatFits.height = height
        }
        return sizeThatFits
    }
}

Set CustomTabBar class for the UITabBar in the Identity Inspector (⌥⌘3):

Tab Bar Identity Inspector

Then set desired Height (greater than 0.0) in the Attributes Inspector (⌥⌘4):

Tab Bar Attributes Inspector

Solution 5

Create a custom subclass of type UITabBar, then implement the following method :

@implementation CustomTabBar
#define kTabBarHeight = // Input the height we want to set for Tabbar here
-(CGSize)sizeThatFits:(CGSize)size
{
    CGSize sizeThatFits = [super sizeThatFits:size];
    sizeThatFits.height = kTabBarHeight;

    return sizeThatFits;
}
@end

Hope this will work.

Share:
97,050
Geek
Author by

Geek

iOS, Android

Updated on February 04, 2022

Comments

  • Geek
    Geek over 2 years

    I use UITabBarController as a root view and app supports iOS 6 and above. Project class hierarchy is as below.

    UITabBarController
      - tab1
        - UINavigationController
          - UIViewController
          - UIViewController
          .
          .
      - tab2
        - UINavigationController
          - UIViewController
          - UIViewController
          .
          .
          .
      - tab3
        - UIViewController
      - tab4
        - UIViewController
    

    I used below code to change height of UITabBar in one of the UIViewControllers (which is inside UINavigationController) in above hierarchy.

    CGRect tabbarFrame = self.tabBarController.tabBar.frame;
    tabbarFrame.size.height += 60;
    self.tabBarController.tabBar.frame = tabbarFrame;
    

    But its not changing the height. UITabBar is displayed with default height. Though logging its value prints changed value as shown below.

    <UITabBar: 0xb528f60; frame = (0 431; 320 109); autoresize = W+TM; layer = <CALayer: 0xb529080>>
    

    How can I change UITabBar's height to achieve something like this:?

    enter image description here

  • voghDev
    voghDev over 9 years
    can you specify a bit more? i've added this code to my class that extends TabBarController and nothing happened
  • voghDev
    voghDev over 9 years
    I discarded changing tabBar height because it is a constant defined by Apple, but still couldn't do it (in case I'd be finally interested in resizing it).
  • Rock
    Rock about 9 years
    @MS_iOSDeveloper: What do you mean "connect it to storyboard VC"? How to connect it? Thanks!
  • MB_iOSDeveloper
    MB_iOSDeveloper about 9 years
    You go to your storyboard. Click the viewcontroller, and go to the right side of Xcode to the "view inspector". Under the third tab (which looks like a newspaper) you will find a "Class" Label. The placeholder grey text should say "UIViewController". There you type the name of your viewcontroller file ,ex. "DNMainTabVC". After that a arrow will appear in the Box beside "DNMainTabVC". This means that the viewcontroller file (.swift) is connected to the storyboard element. What ever you write in "DNMainTabVC.swift" will have effect on the storyboard VC.
  • Rock
    Rock about 9 years
    @MS_iOSDeveloper got it. so it's selecting custom class. I thought you meant some "dragging" action to "connect". I got it work. thanks for explaining!
  • vilanovi
    vilanovi about 9 years
    Great! This so far is the best solution I've seen. As it doesn't modify directly the frame but instead changes the expected size! Great!
  • Dklionsk
    Dklionsk over 8 years
    Your viewWillLayoutSubviews implementation should call super, probably as the first line.
  • dmirkitanov
    dmirkitanov over 8 years
    @Dklionsk It could call super, but it doesn't have to: The default implementation of this method does nothing. (from the docs)
  • Alex Pretzlav
    Alex Pretzlav over 8 years
    @dmirkitanov that's true for a UIViewController but may not be true for UITabBarController
  • jaytrixz
    jaytrixz about 8 years
    Not working anymore in Swift 2.2. It leaves a clear space below the original tab bar frame
  • Kqtr
    Kqtr about 7 years
    @jaytrixz Had the same issue. The blank space will appear if you put Alvin's code in viewDidLoad(), but not if you put it in viewWillLayoutSubviews() as suggested
  • SaundersB
    SaundersB about 7 years
    Swift 3.0 version. import Foundation import UIKit class NavigationTabBarController: UITabBarController{ let kBarHeight = CGFloat(80) override func viewWillLayoutSubviews() { var tabFrame = self.tabBar.frame //self.TabBar is IBOutlet of your TabBar tabFrame.size.height = kBarHeight tabFrame.origin.y = self.view.frame.size.height - kBarHeight self.tabBar.frame = tabFrame } }
  • Alexander Larionov
    Alexander Larionov almost 7 years
    Be careful! The behavior is undefined as to which method implementation is used at runtime - original from UITabbar class or your extension
  • rockdaswift
    rockdaswift almost 7 years
    Works like charm
  • Roberto
    Roberto over 6 years
    You should NOT be overriding methods using Swift extensions (or Objective-C categories, for that matter). If you want to use the sizeThatFits() approach, use this solution instead: stackoverflow.com/a/46425620/538491
  • Vipin Johney
    Vipin Johney over 6 years
    Have you thought about making an extension instead of Custom Class. And then specifying @IBInspectable var height in the extension. If that is possible, the second step of specifying the Custom Class can be avoided.
  • Taku
    Taku about 6 years
    This answer does not have side effects in terms of auto layout of the inner view controllers, and it should be the accepted answer.
  • jakedunc
    jakedunc almost 6 years
    This will make the tabBar jump when animating a view change (like a status bar hiding)
  • Jindřich Skeldal
    Jindřich Skeldal over 5 years
    Doesn't works well on iPhone X. You have to use this solution: stackoverflow.com/a/50346008/1702909
  • Peter Lapisu
    Peter Lapisu over 5 years
    doesn't work well with scrollviews which dont adjust accordingly
  • John
    John over 5 years
    This works, however some of the view got blocked by tab bar because of the increased height.. Any idea how to solve this?
  • Kqtr
    Kqtr over 5 years
    Hey @john. Are you pinning them to the safe area bottom margin?
  • John
    John over 5 years
    Hi @Kqtr, I pinned the view to the bottom view like: NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutAttribute.equal, toItem: view, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0) I found safeAreaInsets and safeAreaLayoutGuide but the feature only available for iOS 11 and above. Is this what you're referring to?
  • Kqtr
    Kqtr over 5 years
    Yes, you could try, on iOS 11 and above, to use view.safeAreaLayoutGuide.bottomAnchor, where view is the VC's main view. And below iOS 11, pin to VC's bottomLayoutGuide.topAnchor. Currently, you are using the view's bottom, and the view might go lower than those bottom guides.
  • Kqtr
    Kqtr over 5 years
    @john also, FYI, for convenience I created 4 variables in an VC extension that provides simple constraints to use (repeat for left right & top): extension UIViewController { var safeBottomAnchor: NSLayoutYAxisAnchor { if #available(iOS 11.0, *) { return view.safeAreaLayoutGuide.bottomAnchor } else { return bottomLayoutGuide.topAnchor } } }
  • John
    John over 5 years
    good one, I have done that but did it as a UIView extension, like: extension UIView { var safeTopAnchor: NSLayoutYAxisAnchor { if #available(iOS 11.0, *) { return self.safeAreaLayoutGuide.topAnchor } else { return self.topAnchor } } Thank for sharing BTW 😀
  • Kqtr
    Kqtr over 5 years
    My pleasure! And careful because below iOS 11, I suspect that your extension will pin to the top of the view which, in the case of a VC's main view, will be the top of the status bar, whereas it will be the bottom of the status bar using the VC's topLayoutGuide.
  • ioio007
    ioio007 over 5 years
    @jakedunc I think it's the issue that S. Azzopardi said, I put this code in viewDidLayoutSubviews() and it works fine.
  • Saravanan
    Saravanan almost 5 years
    @ioio007 Hi this works fine for iPhone x and other devices. But when i increase the height UIView bottom is hiding according the increase value. Help me to get the solution.
  • ioio007
    ioio007 almost 5 years
    Hi @Saravanan, looks like your problem is the same with the comment below this answer: stackoverflow.com/a/44293634/7144402
  • Bhavin Bhadani
    Bhavin Bhadani almost 5 years
    How can we use this when we make tab bar controller programmatically?
  • kelin
    kelin almost 5 years
    @dmirkitanov, the default implementation of UIViewController does nothing, but it's a UITabBarController subclass!
  • arlomedia
    arlomedia over 4 years
    Changing viewWillLayoutSubviews to viewDidLayoutSubviews works in iOS 13.
  • Omar Awamry
    Omar Awamry over 4 years
    doesn't really work for iphonex because of the bottom line thing.
  • mauricioconde
    mauricioconde over 4 years
    I used this method definition inside an extension, because I'm creating all the UI elements programmatically and, when I tried to set the tabBar of my tabBarController by overriding the tabBar attribute, it displays an empty tabBar (without items)
  • Chandan Jee
    Chandan Jee almost 4 years
    guard let window = UIApplication.shared.keyWindow is deprecated in iOS 13.0. So please update.
  • Sahil Omer
    Sahil Omer over 3 years
    Change viewWillLayoutSubviews to viewDidLayoutSubviews in UITabBarViewController Class It will work fine. it is worked for me.
  • Eric Aya
    Eric Aya over 2 years
    This is the same solution as in this other answer (and other ones). When answering older questions that already have answers, please make sure you provide either a novel solution or a significantly better explanation than existing answers.
  • Admin
    Admin over 2 years
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
  • Balázs Vincze
    Balázs Vincze over 2 years
    This combined with moving the tab bar item title and image down, to have them centered is probably the neatest solution. Thx!