iOS 7 UIBarButtonItem ridiculous spacing issue
Asked Answered
I

2

8

I'm having an issue that so far I cannot find a solution to. I am adding a new feature to my app and wish to add a second UIBarButtonItem on the left side of my UINavigationBar. For some reason iOS 7 takes this as a button1, grandCanyon, button2. I cannot find any way to remove the ridiculous spacing between these two buttons, which is also causing my title to be out of alignment. Can anyone help!? Is there a solution to this!?

enter image description here

Code:

UIBarButtonItem *firstButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"firstButton"] style:UIBarButtonItemStylePlain target:self action:@selector(showSettings)];
UIBarButtonItem *secondButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"secondButton"] style:UIBarButtonItemStylePlain target:self action:@selector(showAttachments)];
[self.navigationItem setLeftBarButtonItems:[NSArray arrayWithObjects:firstButton, secondButton, nil]];
Irregularity answered 10/10, 2013 at 21:24 Comment(3)
Show your code for setting up the buttons.Florin
Put the code in your question so people can read it.Florin
Oops, done. Didn't realise I could edit the post, sorry.Irregularity
I
4

Think I've managed to sort out the problem using a custom view as shown below, it's not perfect (selection dims the buttons darker rather than lighter for example) but I'll try fixing that tomorrow. Just glad my headache is over! Thank you for your help, it lead me to a few new approaches I didn't try.

UIImage *firstButtonImage = [UIImage imageNamed:@"firstButton"];
firstButtonImage = [firstButtonImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

UIButton *firstButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
[firstButton setImage:firstButtonImage forState:UIControlStateNormal];
[firstButton addTarget:self action:@selector(firstButtonPressed) forControlEvents:UIControlEventTouchUpInside];

UIImage *secondButtonImage = [UIImage imageNamed:@"secondButton"];
secondButtonImage = [secondButtonImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

UIButton *secondButton = [[UIButton alloc] initWithFrame:CGRectMake(45, 0, 35, 35)];
[secondButton setImage:secondButtonImage forState:UIControlStateNormal];
[secondButton addTarget:self action:@selector(secondButtonPressed) forControlEvents:UIControlEventTouchUpInside];

UIView *leftBarItemsView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 35)];
[leftBarItemsView addSubview:firstButton];
[leftBarItemsView addSubview:secondButton];

UIBarButtonItem *leftBarItem = [[UIBarButtonItem alloc] initWithCustomView:leftBarItemsView];

[self.navigationItem setLeftBarButtonItems:[NSArray arrayWithObject:leftBarItem]];
Irregularity answered 12/10, 2013 at 4:43 Comment(2)
Thanks a lot for this. I came across this same issue today and solved it using your answer.Expressionism
It seems that in iOS 7 it also spreads out UIBarButtonItems in a UIToolbar. I have set mine to button, label, button, label, flexible space, and it is shown as button, label, flexible, button, labelLysozyme
I
2

There may be a better way, but to correct spacing issues on bar button items on iOS 7, I've subclassed UINavigationBar and overridden the layoutSubviews method. There you can move each bar button item wherever you want.

As an example:

- (void)layoutSubviews
{
    [super layoutSubviews];

    // If iOS 7, fix the bar button positions
    BOOL isIOS7 = [[[UIDevice currentDevice] systemVersion] compare:@"7" options:NSNumericSearch] != NSOrderedAscending;
    if (isIOS7)
    {
        for (UIBarButtonItem *item in self.topItem.leftBarButtonItems)
        {
            // Reposition the customView property
        }

        for (UIBarButtonItem *item in self.topItem.rightBarButtonItems)
        {
            // Reposition the customView property
        }
    }
}

Actually, as I looked at my code, I was using UIBarButtonItems with custom views. So I was able to move the custom view position.

You will likely need to loop through the subviews of the UINavigationBar to move them if you're just using UIBarButtonItems with images like this:

- (void)layoutSubviews
{
    [super layoutSubviews];

    // If iOS 7, fix the bar button positions
    BOOL isIOS7 = [[[UIDevice currentDevice] systemVersion] compare:@"7" options:NSNumericSearch] != NSOrderedAscending;
    if (isIOS7)
    {
        for (UIView *subview in self.subviews)
        {
            // Reposition as needed
        }      
    }
}
Inappreciable answered 11/10, 2013 at 2:54 Comment(6)
Do you have an example of what you have changed in drawRect:, not sure how I would go about this.Irregularity
Updated. Also good thing you asked, I had misremember and it's the layoutSubviews method, not drawRect.Inappreciable
I just updated my answer again, let me know if that works for youInappreciable
I'm not very good at this :\ How would I go about using a subclassed UINavigationBar? If I try an assign it to a navigation controller it tells me it's a read only property.Irregularity
I've noticed that if I use a standard system item the spacing is fine, but when I use a custom image this is when the spacing becomes excessive. Is it perhaps something to do with the way the UIBarButtonItem handles the UIImage, or something to do with the UIImage?Irregularity
Sorry for the late reply, but looks like you've got a solution. Please remember to upvote my answer if it helped you. Also if you solved your problem with your own answer you can select that as the correct answer so that the question will be marked as solved.Inappreciable

© 2022 - 2024 — McMap. All rights reserved.