103

Normally on each tab of a UITabBar you have a small image and a title naming the tab. The image is positioned/centred towards the top of the tab to accommodate the title underneath. My question is: if you want to have a tabBar with just an image and no title is there a way to move the image down so it centers better within the tab?

I am using (see below) currently:

[tabBarItem setFinishedSelectedImage:tabSelected withFinishedUnselectedImage:tabUnselected];

but would prefer to use to larger image with no title, at the moment if I make the image bigger than about 70pixels@2x it starts edging off the top of the UITabBar whilst leaving a lot of unused space at the bottom.

Marcus Adams
  • 49,523
  • 8
  • 81
  • 132
fuzzygoat
  • 25,797
  • 45
  • 159
  • 288

9 Answers9

186

Try adjusting tabBarItem's imageInsets (for moving the icon image) and setting the controllers title to nil (so no title is displayed). Put something like this to -init or -viewDidLoad method in view controller:

Objective-C

self.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0);
self.title = nil;

Swift

self.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
self.title = nil

UITabBarItem is a subclass of UIBarItem which has UIEdgeInsets imageInsets property. Play a little with the insets until it looks good (depending on your tabbar icon images)

Lukas Kukacka
  • 7,404
  • 2
  • 21
  • 47
153

You can do it via storyboard too. Select your tabbaritem, go to size inspector and assign the appropriate insets.

enter image description here

*Demonstrated on Xcode, Version 7.3.1 (7D1014)

Neil Galiaskarov
  • 4,760
  • 2
  • 23
  • 45
52

Make a subclass of UITabBarController, and in its viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.viewControllers enumerateObjectsUsingBlock:^(UIViewController *vc, NSUInteger idx, BOOL *stop) {
        vc.tabBarItem.title = nil;
        vc.tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -5, 0);
    }];
}

Swift 3:

for vc in self.viewControllers! {
    vc.tabBarItem.title = nil
    vc.tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -5, 0)
}
Brian
  • 26,298
  • 13
  • 78
  • 84
  • this worked for me. just that for swift the method enumerateObjectsUsingBlock is not available any more – Junchao Gu Jun 21 '15 at 06:54
  • don't subclass, instead put this in to your AppDelegate – Laszlo Apr 22 '16 at 14:13
  • 1
    putting this snippet in `AppDelegate` also works, but it's not obviously better than subclassing it. You can have your own preference though :) – Brian Apr 25 '16 at 03:26
11

This worked for me

Swift 4

let array = tabBarController?.customizableViewControllers
for controller in array! {
    controller.tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -5, 0)
}
Ahmadreza
  • 5,262
  • 2
  • 36
  • 55
10

If you're using Xamarin, this works:

screen.TabBarItem.ImageInsets = new UIEdgeInsets(5, 0, -5, 0);
screen.TabBarItem.Title = "";
Jelle
  • 356
  • 2
  • 11
2

SWIFT 3.0

You can set image lnsets, set top,left,bottom and right according desing.

self.tabBarItem.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: 0, right: 0)
krish
  • 2,498
  • 19
  • 25
2

For iOS 11 you need to override TraitCollection method apart from setting ImageInsets. Please add the method in your subclassed UITabBarController class

public override UITraitCollection TraitCollection {
 get {
  return UITraitCollection.FromHorizontalSizeClass(horizontalSizeClass: UIUserInterfaceSizeClass.Compact);
 }
}
Prashant
  • 224
  • 2
  • 14
  • Good tip that helped me solve an issue related to the image position for tab bar item on iPad and iOS 11. But it's too harsh to override the trait collection at the view controller level, it's better to subclass the UITabBar class and override the traitCollection property there. Also returning a trait collection with only the horizontal class, will drop other trait collection properties. `return UITraitCollection(traitsFrom: [ super.traitCollection, UITraitCollection(horizontalSizeClass: .compact)])` did the trick for me. – Emmanuel Paris Jan 09 '18 at 20:30
0

In Swift 4.2, UIEdgeInsetsMake is depricated, instead we should use UIEdgeInsets,

let array = tabBarController?.customizableViewControllers
    for controller in array! {
        controller.tabBarItem.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0)
    }
Bappaditya
  • 8,676
  • 2
  • 15
  • 27
0

These didn't work for me, the only solution that worked was setting the alignmentRectInsets when adding the image. Here's what mine looked like:

let newsView = NewsViewController()
let newsIcon = UITabBarItem(title: nil, image: UIImage(systemName: "newspaper")?.withAlignmentRectInsets(UIEdgeInsets(top: 8.5, left: 0, bottom: -8.5, right: 0)), tag: 0)
newsView.tabBarItem = newsIcon
let viewControllers = [newsNavController]
self.viewControllers = viewControllers
Michael
  • 379
  • 2
  • 10