Question

I have a nav bar in an iPhone app with a custom UIBarButtonItems in it:

UIBarButtonItem* homePersonButton = [[UIBarButtonItem alloc]
       initWithImage:[UIImage imageNamed:@"homePerson.png"]
               style:UIBarButtonItemStylePlain
              target:self action:@selector(showHomePerson)];

The homePerson.png is 20 x 18.

It looks good in portrait mode, but in landscape mode the 20x18 image on the button is too tall to look nice. It looks like iOS does some work on their standard buttons to shrink the image as needed when it is in a thinner nav bar.

What is the best way to handle this?

Another example is when I have a custom button in the titleView of the nav bar. I need it to shrink as well when the app rotates.

Thanks in advance for any pointers you can give me!

Was it helpful?

Solution

The size of a toolbar and navigation bar image is 20 x 20 so when you're providing an image that does not meet those dimensions you're leaving up to the framework to resize/scale your image which is causing your problem. Resize/scale your image to 20x20 and your image should look correct in both portrait and landscape.

OTHER TIPS

steipete mentioned this in the comments but I feel like it needs to be an answer now. As of iOS 5, you can use the UIBarButtonItem initializer:

- initWithImage:landscapeImagePhone:style:target:action:

Just set landscapeImagePhone image to a smaller version of the image you want resized in landscape.

After some testing, I noticed that the iPhone does shrink down the navigation bar and therefore the UIBarButtonItems on the navigation bar but the iPhone 6 Plus does not. The 6 Plus seems to keep the navigation bar at a height of 44px, whereas the regular iPhone shrinks it down to 32px. Because of this, the 6 Plus also does not use the landscapeImagePhone in landscape.

I tested this by not just using a smaller size image for landscapeImagePhone, but a completely different image. The image never changed on the 6 Plus.


However, be aware of the following as of iOS 9.2 on the iPhone 6 Plus:

The Apple documentation for this initializer states that landscapeImagePhone is:

The image to be used for the item in landscape bars in the UIUserInterfaceIdiomPhone idiom.

As of iOS 9.2, the 6 Plus does report as UIUserInterfaceIdiomPhone in both portrait and landscape. Before, the 6 Plus used to be UIUserInterfaceIdiomUnspecified. I'm not exactly sure when that was updated. But, since it is now UIUserInterfaceIdiomPhone, according to the documentation, the landscapeImagePhone should apply to the 6 Plus as well.

So maybe it doesn't rely so much on the UIUserInterfaceIdiom as much as it does on the height of the navigation bar. I do not know for sure. Just note that this inconsistency may be "fixed" in the future and therefore cause a different behavior.

I have similar issue. Now i use the custom type to button. e.g. here is my catalog of UIBarButtonItem. you can use it to build a custom bar button.

+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image highlightedImage:(UIImage *)highlightedImage     target:(id)target action:(SEL)action{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setBackgroundImage: [image stretchableImageWithLeftCapWidth:7.0 topCapHeight:0.0] forState:UIControlStateNormal];
    button.frame= CGRectMake(0.0, 0.0, image.size.width, image.size.height);
    [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:button];

    return barItem;
}

Then you can adjust the bar Button custom view frame when rotate.

tip:

  1. in the rotate method, e.g. willAnimateRotationToInterfaceOrientation, print the custom view frame of the navigation bar button items.., and get the correct frame (in protrait mode) you want, also, you can see the frame is incorrect in landscape mode, we need to fix it.
  2. fix the landscape bar button frame issue by referencing to the correct frame value.

in my case, i just simple fix the origin of the custom view... e.g.

// adjust the navigation Item top, otherwise it is not proper set after rotation
_centralRootViewController.navigationItem.leftBarButtonItem.customView.top = 5;
_centralRootViewController.navigationItem.rightBarButtonItem.customView.top = 5;

Note: top is the y of frame.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top