Skip to content

Instantly share code, notes, and snippets.

@calt
Last active January 9, 2024 05:58
Show Gist options
  • Star 41 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save calt/7ea29a65b440c2aa8a1a to your computer and use it in GitHub Desktop.
Save calt/7ea29a65b440c2aa8a1a to your computer and use it in GitHub Desktop.
UITabBar with custom height in Swift, does not work for iOS 14 or later.
// Does not work on iOS 14.0 or later, keeping the gist just for reference.
extension UITabBar {
override open func sizeThatFits(size: CGSize) -> CGSize {
super.sizeThatFits(size)
var sizeThatFits = super.sizeThatFits(size)
sizeThatFits.height = 71
return sizeThatFits
}
}
@zjfjack
Copy link

zjfjack commented Nov 28, 2017

Best solution! Better than viewwilllayoutsubviews, that will cause wired problem.
But seems it also has some problems when using iPhone X

@artem-shmatkov
Copy link

Thanks!

@j-pk
Copy link

j-pk commented Jan 3, 2018

Solution that works across all devices including iPhone X. You may need to add a check for iOS 11 availability in the guard statement if developing for iOS 10 or lower.

override open func sizeThatFits(_ size: CGSize) -> CGSize {
    super.sizeThatFits(size)
    guard let window = UIApplication.shared.keyWindow else {
        return super.sizeThatFits(size)
    }
    var sizeThatFits = super.sizeThatFits(size)
    sizeThatFits.height = window.safeAreaInsets.bottom + 40
    return sizeThatFits
}

@zolobdz
Copy link

zolobdz commented May 16, 2018

very well,This solution is great!

@Rotemy
Copy link

Rotemy commented Aug 14, 2018

Great job! working like a charm

@mertala
Copy link

mertala commented Jan 31, 2019

thanks for solution!!!!

@amrit42087
Copy link

Hi,

The solution seems to be perfect. But where do I need to call this extension from? Is it from viewwilllayoutsubviews?

Thanks

@tronxdev
Copy link

tronxdev commented Jul 2, 2019

Replace public with open.

extension UITabBar {
    override open func sizeThatFits(size: CGSize) -> CGSize {
        super.sizeThatFits(size)
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = 71
        return sizeThatFits
    }
}

@mohsinbmwm3
Copy link

Thanks, It worked nicely.

@Violetdusk
Copy link

Thanks, you saved my day :)

@andrew-nemtsev
Copy link

It works at iOS 13.3 but didn't work at iOS 13.4 due to UITabBar.sizeThatFits() is never called

@mikhailpanfilov
Copy link

It works at iOS 13.3 but didn't work at iOS 13.4 due to UITabBar.sizeThatFits() is never called

The same for me. Have you got any solution?

@christianpbrink
Copy link

Same problem here!

@jcrooke
Copy link

jcrooke commented May 5, 2020

I have found a solution for iOS 13.4 that doesn't require too much to be changed.

First step is to change your code (I'll use the example above, but your code might be slightly different if you've done something custom);

Change from this;

extension UITabBar {
    override open func sizeThatFits(size: CGSize) -> CGSize {
        super.sizeThatFits(size)
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = 71
        return sizeThatFits
    }
}

To this;

class CustomTabBar : UITabBar {
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        super.sizeThatFits(size)
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = 71
        return sizeThatFits
    }
}

Then in your storyboard, click your "Tab Bar Controller"'s tab bar and change the class from UiTabBar to CustomTabBar. This ensures that sizeThatFits is called.

@RemiRodrigues
Copy link

If you've created your UITabBarController programmatically, you can set custom class for UITabBar class like this :

init() {
       super.init(nibName: nil, bundle: nil)
       object_setClass(self.tabBar, CustomTabbar.self)

       /* some stuff here */ 
}

That's a bit weird because Apple don't let us set a custom instance of UITabBar.

@anatoliykant
Copy link

anatoliykant commented Aug 26, 2020

If you've created your UITabBarController programmatically, you can set custom class for UITabBar class like this :

init() {
       super.init(nibName: nil, bundle: nil)
       object_setClass(self.tabBar, CustomTabbar.self)

       /* some stuff here */ 
}

That's a bit weird because Apple don't let us set a custom instance of UITabBar.

@RemiRodrigues thx, you saved me a lot of time

@Prathap-iOS
Copy link

I have found a solution for iOS 13.4 that doesn't require too much to be changed.

First step is to change your code (I'll use the example above, but your code might be slightly different if you've done something custom);

Change from this;

extension UITabBar {
    override open func sizeThatFits(size: CGSize) -> CGSize {
        super.sizeThatFits(size)
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = 71
        return sizeThatFits
    }
}

To this;

class CustomTabBar : UITabBar {
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        super.sizeThatFits(size)
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = 71
        return sizeThatFits
    }
}

Then in your storyboard, click your "Tab Bar Controller"'s tab bar and change the class from UiTabBar to CustomTabBar. This ensures that sizeThatFits is called.

Thanks @jcrooke This is working awesomely.

@Stebulis
Copy link

Stebulis commented Oct 23, 2020

I hope I'm missing something, but there's no way for me to make any of those solutions work.

In my project, UITabViewController is an initial controller and no matter what I do, the default size of the tab bar is loaded first and it changes to the new height defined with the override of sizeThatFits shortly after.

So I load the tab bar twice and it has this buggy look when the height of the tab bar changes.

I'm running iOS 14.1 and I' have tried older devices before iPhone X too in a simulator.

Any help is appreciated.

@Erumaru
Copy link

Erumaru commented Oct 31, 2020

nothing from mentioned here works for me in iOS 14+

@daviddelmonte
Copy link

Same here unfortunately

@Wei18
Copy link

Wei18 commented Nov 23, 2020

Work for me in iOS 14+, and others

class WeiTabBarController: UITabBarController {
    
    init() {
        
        super.init(nibName: nil, bundle: nil)
        
        object_setClass(self.tabBar, WeiTabBar.self)
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    class WeiTabBar: UITabBar {
        
        override func sizeThatFits(_ size: CGSize) -> CGSize {
            
            var sizeThatFits = super.sizeThatFits(size)
            
            sizeThatFits.height = 120
            
            return sizeThatFits
            
        }
        
    }
    
}

@Onyekachi-152
Copy link

@RemiRodrigues Thanks, you really saved me a lot of headaches.

@afaqsaqi
Copy link

@Wei18 Thank you man it works like a charm!

@homerblr
Copy link

homerblr commented Sep 7, 2021

@Wei18 you are a champ

@kepe94
Copy link

kepe94 commented Sep 7, 2021

Hi, This method works but how can I center the tab bar image to the updated height?
410AE454-7D74-42A2-A769-6F96B2B80607

@MoSaber-hub
Copy link

@Wei18 Thank you that's work for me too on iOS 14+

@ardacmen
Copy link

ardacmen commented Apr 12, 2023

@Wei18 thank you! still working for swift 5+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment