UIBarButtonItems with background images

391 views Asked by At

We have a "bottom bar" in our app which at the moment is just a UIView and defined all over the place which leads to inconsistency etc...

I'm trying to replace the use of the this with a UIToolBar and UIBarButtonItems so I can customise the appearance with the UIAppearance protocol.

The buttons we use in the tool bar have a background image made of a resizable image (defined in asset catalog).

What we want it to look like is something like this...

Desired result

The buttons are nicely centred between the top and bottom of the tool bar.

However, what happens when I set the background image using the UIAppearance protocol is this...

Actual result

The buttons are vertically aligned off centre.

It seems like the text is in the same place and the background is being applied around the text but the text is actually lower than centre. With no BG this makes sense but with a BG it doesn't work.

I could change the frame in code of every button but this is not ideal as we get back to the inconsistency problem that I'm trying to solve.

Is there any way to change this for all instances of UIBarButtonItem in one place?

I even tried adding transparency to the bottom of the image to "push it upwards" but it didn't have an effect.

Update to show the problem in place

In a enw project I embed a view controller in a navigation controlle rand use this code...

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    [self.navigationController setToolbarHidden:NO animated:animated];
}

- (NSArray *)toolbarItems
{
    return @[
             [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil],
             [[UIBarButtonItem alloc] initWithTitle:@"Hello" style:UIBarButtonItemStyleDone target:nil action:nil],
             [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil],
             [[UIBarButtonItem alloc] initWithTitle:@"World!" style:UIBarButtonItemStyleDone target:nil action:nil],
             [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
             [[UIBarButtonItem alloc] initWithTitle:@"Goodbye!" style:UIBarButtonItemStyleDone target:nil action:nil],
             [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]
             ];
}

The result is...

Default toolbar style

Then I use the UIAppearance code...

[[UIToolbar appearance] setTintColor:[UIColor whiteColor]];
[[UIToolbar appearance] setBarTintColor:[UIColor colorWithRed:0.15 green:0.2 blue:0.85 alpha:1.0]];

And the result is...

Blue toolbar with white tint colour.

This looks fine but when I add the background image...

Resizable button image

With the code...

[[UIBarButtonItem appearance] setBackgroundImage:[UIImage imageNamed:@"ToolBarButtonBackgroundEnabled"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

I see this...

Button backgrounds are below centre

I tried changing the title position adjustment...

[[UIBarButtonItem appearance] setTitlePositionAdjustment:UIOffsetMake(0, -5) forBarMetrics:UIBarMetricsDefault];

But that just moves the text inside the button...

Buttons with offset titles

It doesn't move the button background.

I can't find anything relating to the offset of the buttons in the toolbar appearance.

Moving Text

I was wrong about the text staying int he same place. The text moves when you add a background to the bar button items...

Merged image of with and without background

I merged screenshots of the toolbar with and without the button backgrounds. You can see that the text is moved downwards.

2

There are 2 answers

1
Ghanshyam Tomar On

Have you tried [xyzbtn setImageEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 10)]; or your image size is greater than your button's size, so it might be affecting the layout.

0
Ben On

I have noticed the same thing: if you set a background image, the UIBarButtonItem moves down by 3pt. It also moves right by 1pt.

This doesn't seem to happen in iOS 11, which is good news.

My conjecture is that Apple made the assumption that if you have a background image set you're trying to indicate a 'selected' button state, and they deliberately move he button down and right a bit to give a 3-D movement appearance.