How to properly position the back button in iOS7

23,135

Solution 1

EDIT
I think I might have found the trick (in iOS 7 Design Resource -- UIKit User Interface Catalog.)
Under Bar Button Items

Note that a bar button image will be automatically rendered as a template image within a navigation bar, unless you explicitly set its rendering mode to UIImageRenderingModeAlwaysOriginal. For more information, see Template Images.

Under Template Images they have some code to specify the UIImageRenderingMode.

UIImage *myImage = [UIImage imageNamed:@"back"];
UIImage *backButtonImage = [myImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];  
// now use the new backButtomImage
[[UINavigationBar appearance] setBackIndicatorImage:backButtonImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:backButtonImage];

Try creating the UIImage with alignment insets and then set the Back Indicator image.

UIEdgeInsets insets = UIEdgeInsetsMake(10, 0, 0, 0); // or (0, 0, -10.0, 0)
UIImage *alignedImage = [[UIImage imageNamed:@"back"] imageWithAlignmentRectInsets:insets];  
[[UINavigationBar appearance] setBackIndicatorImage:alignedImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:alignedImage];

You might also try adjusting the position of the UINavigationBar title text

[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics];

Solution 2

Well just follow one of the suggestions to fix the layout and lose the iOS 7 "back gesture", and then fix it with a UIScreenEdgePanGestureRecognizer!

A UIScreenEdgePanGestureRecognizer looks for panning (dragging) gestures that start near an edge of the screen. The system uses screen edge gestures in some cases to initiate view controller transitions. You can use this class to replicate the same gesture behavior for your own actions.

Solution 3

PLEASE SEE EDIT BELOW!!!

I created a custom back button in iOS7 not too long ago. Mine has an arrow and the word back on it. I do think pawan's suggestion is a good start. To create the back button with your custom image you can use,

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:self action:@selector(backButtonClicked)];
[backButton setBackgroundImage:finalImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[backButton setTitlePositionAdjustment:UIOffsetMake(-20, 0) forBarMetrics:UIBarMetricsDefault];

self.navigationItem.leftBarButtonItem = backButton;

My image finalImage is a composite of two different images, but you can just use your "back" image. But I think that is where the problem lies. My image was a composite, you might want to make a composite as well, but put a clear space above your back icon. I placed a clear space to the right of my icon to adjust it's spacing. Here is the code,

UIImage *arrow = [UIImage imageNamed:@"back.png"];
UIImage *wordSpace = [UIImage imageNamed:@"whiteSpace.png"];
CGSize size = CGSizeMake(arrow.size.width + wordSpace.size.width, arrow.size.height);
UIGraphicsBeginImageContext(size);
[arrow drawInRect:CGRectMake(0, 0, arrow.size.width, size.height)];
[wordSpace drawInRect:CGRectMake(arrow.size.width, 0, wordSpace.size.width, wordSpace.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); 

The Image wordSpace is a clear png that I made in photoshop so my new back button image was not stretched. You might want to place a clear png on top, to push the icon down a little. Make the size.height of it in photoshop for what you think the adjustment should be. You might need to futz with this a bit. And make sure to change up the CGSize so that it fits your icon and the clear space.

My word back was a bit off, so I looked at

[backButton setTitlePositionAdjustment:UIOffsetMake(-20, 0) forBarMetrics:UIBarMetricsDefault];

I had to play around with that line a bit to make it look as good as possible but it finally gave me what I wanted with the -20. I even adjusted the second variable which is 0 in mine, this moved the actual icon around. -5 put the icon down way to far, but its another option from the clear png.

Now to deal with the fact that you want it to be an actual back button. Look at the first line of code I posted. The action on the button is @selector(backButtonClicked). So all you need to do is make that method and you should be good to go!

- (void)backButtonClicked
{
  NSLog(@"going back");
  [self.navigationController popViewControllerAnimated:YES];
}

Hope this helps a bit.

enter image description here

EDIT*****

I was playing around with my code a little bit and found a better way to move the back icon. I just used a ship's wheel because I didn't have the same one that you did, but it will work the same.

Since you don't really want a title you can create the button with this code,

UIImage *image = [UIImage imageNamed:@"781-ships-wheel.png"];

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(backButtonClicked)];

Just change the 781 stuff with your icon's name. Then you can move it around with the following,

[backButton setImageInsets:UIEdgeInsetsMake(20, 0, -20, 0)];

Take a look at this picture.

pic one

This shows the icon down considerably, but I wanted to show you the idea. The numbers for the Edge insets are Top, Left, Bottom, and Right. Don't touch the left and right if you don't need to move it that way, change the top and bottom. Notice however, that if you need to move it down by 20 points like I did, (way too much) you need to offset in the negative for the bottom, or the icon will get compressed. This is what it looks like with all zero's.

pic with zeros

So you can pretty much move it where ever you want, but you will still have to set up the @selector(backButtonClicked) to make it work like the real back button.

Solution 4

This is Swift 2 version. The simplest way is like this. Put this code in AppDelegate.'

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let navigationBarAppearace = UINavigationBar.appearance()
        let image = UIImage(named: "back-btn")
        navigationBarAppearace.backIndicatorImage = image
        navigationBarAppearace.backIndicatorTransitionMaskImage = image

        return true
    }

if your back button has background colour, it may won't work correctly.

Add your icon to asset folder for each resolution like this: enter image description here

Solution 5

You can try this

self.navigationItem.leftBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 0, 10, 0);
Share:
23,135
Bernat
Author by

Bernat

Updated on August 23, 2020

Comments

  • Bernat
    Bernat over 3 years

    I used this code to use a custom image as the back button in the whole app.

    [[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"back"]];
    [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back"]];
    

    The image dimensions are 30 x 30.

    The code adds the image as the back button but the position is not the correct, as you can see in the following image:

    back button not correct positioned

    Any ideas on how to properly position the image without modifying its dimensions (at least the visual part of the image (circle + arrow))?

    EDIT:

    I don't want to use a custom back button because that forces me to disable the swipe/back-gesture in iOS7