2
votes

I'm customizing the elements like navigation bar, tab bar and uibarbuttonitem using UIAppearance. It works very well except for a very strange behavior of the UIBarButtonItem elements. On the top level of the navigation controller hierarchy everything looks good, but if I push the next view controller, the UIBarButtonItem elements move a little bit downwards, but at the same time, the back button stays at its correct position. I attached two images to illustrate my problem.

1) First view controller in the navigation controller hierarchy

enter image description here

2) Second view controller in the navigation controller hierarchy

enter image description here

EDIT: The code

    //Change navigation bar appearance
    [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"GPNavigationBarBackground.png"] forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
    [[UINavigationBar appearance] setShadowImage:[UIImage imageNamed:@"GPNavigationBarShadow.png"]];

    [[UINavigationBar appearance] setTitleTextAttributes:
     [NSDictionary dictionaryWithObjectsAndKeys:
      [UIColor whiteColor], UITextAttributeTextColor,
      [UIFont boldSystemFontOfSize:17], UITextAttributeFont,nil]];
    [[UINavigationBar appearance] setTitleVerticalPositionAdjustment:2.f forBarMetrics:UIBarMetricsDefault];

    UIImage *buttonBackground = [[UIImage imageNamed:@"GPNavigationBarButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)];
    UIImage *buttonPressedBackground = [[UIImage imageNamed:@"GPNavigationBarButtonPressed.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)];

    UIImage *backButtonBackground = [[UIImage imageNamed:@"GPNavigationBarBackButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 10)];
    UIImage *backButtonPressedBackground = [[UIImage imageNamed:@"GPNavigationBarBackButtonPressed.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 10)];

    [[UIBarButtonItem appearance] setBackgroundImage:buttonBackground forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setBackgroundImage:buttonPressedBackground forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];

    [[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonBackground forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonPressedBackground forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];

    [[UIBarButtonItem appearance] setBackButtonBackgroundVerticalPositionAdjustment:1.f forBarMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setBackgroundVerticalPositionAdjustment:1.f forBarMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setTitlePositionAdjustment:UIOffsetMake(0, 1.f) forBarMetrics:UIBarMetricsDefault];
1
Can we see your UIAppearance code and UIbarbuttonItem code?Ryan Poolos

1 Answers

5
votes

Well, after brooding on that problem, I finally solved it. The code above is absolutely correct. The only problem was the height of the background images for the UIBarButtonItem. The UIAppearance proxy lets you set all the graphics, but it doesn't allow you to alter the height of the UIBarButtonItem.

So, when customizing UIBarButtonItem, always remember that a UIBarButtonItem can't be higher than 30pt. That means that custom artwork shouldn't exceed this size.

You can set background images that are higher than 30pt, but you will run into the same problem as stated above.