set custom back bar button universally with no tit

2019-02-10 10:25发布

I want to set custom back bar button for all controllers in the app. I tried using this:

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

It sets the image. That's OK. But, what i really want to do is that, i just want a custom button for back bar button which does not contain any title etc. The code above works, but it adds automated titles and resizes the back bar button item. My need is to have a fixed frame, no-title back bar button item for all controllers in the app.

6条回答
我只想做你的唯一
2楼-- · 2019-02-10 10:45

What i did, was set the backbutton title label alpha to zero, using appearance proxy.

查看更多
该账号已被封号
3楼-- · 2019-02-10 10:48

I've resolved it. Just make a category over UIViewController and import it in prefix.pch file. Then write a method: customViewWillAppear: and swizzle it with viewWillAppear method:

+(void)load{

Method viewWillAppear = class_getInstanceMethod(self, @selector(customViewWillAppear:));

Method customViewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
method_exchangeImplementations(viewWillAppear, customViewWillAppear);

}

Add the above method to that category class. Then implement your customViewWillAppear method like this:

-(void)customViewWillAppear:(BOOL)animated{
    [self customViewWillAppear:animated];
    if([self.navigationController.viewControllers indexOfObject:self] != 0  && !self.navigationItem.hidesBackButton){
        UIBarButtonItem *cancelBarButton = nil;
        UIButton* cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [cancelButton addTarget:self action:@selector(popViewControllerWithAnimation) forControlEvents:UIControlEventTouchUpInside];
        [cancelButton setBackgroundImage:[UIImage imageNamed:@"yourImage.png"] forState:UIControlStateNormal];
        [cancelButton sizeButtonToFit];

        cancelBarButton = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];

        NSMutableArray * leftButtons = [NSMutableArray arrayWithObject:cancelBarButton];
        [leftButtons addObjectsFromArray:self.navigationItem.leftBarButtonItems];
        [self.navigationItem setLeftBarButtonItem:nil];
        [self.navigationItem setLeftBarButtonItems:leftButtons];
    }

    [self.navigationItem setHidesBackButton:YES];
}
-(void)popViewControllerWithAnimation{
    [self.navigationController popViewControllerAnimated:YES];
}

Now, for every controller in your code, you have a custom back button. This took me a lot of time to implement and figure out. Hope it'll help you guys all too.

EDIT: Please use the following code to support iOS7> back swipe feature;

UIImage *image = [UIImage imageForName:@"some_image"];
navBar.backIndicatorImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
navBar.backIndicatorTransitionMaskImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

Create a base view controller and add the following code;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}
查看更多
一纸荒年 Trace。
4楼-- · 2019-02-10 10:52

try this code:

UIButton *tempbtn = [[UIButton alloc] init];
[tempbtn setImage:[UIImage imageNamed:@"testbtn.png"] forState:UIControlStateNormal];
UIBarButtonItem *temp = [[UIBarButtonItem alloc] initWithCustomView:tempbtn];
self.navigationItem.rightBarButtonItem = temp;
查看更多
淡お忘
5楼-- · 2019-02-10 11:00

You could write a category like this,

//
//  UINavigationItem+BarAditions.h
//
//  Created by Satheeshwaran on on 7/5/13.
//


#import <Foundation/Foundation.h>


@interface UINavigationItem (PersonaAddition)

- (void)setCustomBackButton;

@end


//
//  UINavigationItem+BarAditions.m
//
//  Created by Satheeshwaran on on 7/5/13.
//

#import "UINavigationItem+PersonaAddition.h"


@implementation UINavigationItem (PersonaAddition)

- (void)setCustomBackButton 
{
    //customize ur back button here.
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    backButton.frame=CGRectMake(0, 0, 60, 30);
    [backButton addTarget:target action:@selector(didPressLeftItem:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    self.leftBarButtonItem = barItem;    

}

and import this category in all ur files and call the setCustomBackButton in all ur classes. This works fine for me, even in iOS 7.

In ViewDidLoad of all ur classes.

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.navigationItem setCustomBackButton];

}
查看更多
Animai°情兽
6楼-- · 2019-02-10 11:04

I've had a similar problem before and I've searched everywhere for a solution.

The only one I've found, which works for your problem was to implement in EVERY view controller a UILeftBarButton which does the popping.

You can change the background image the way you're doing, but if you set the text to nil or empty text (""), you're button just won't show up.

You also can't change the View of the UIBackBarButton, only it's text (so no custom button).

查看更多
我命由我不由天
7楼-- · 2019-02-10 11:08

My code in ViewDidLoad:

// Set back button image
if ([[self.navigationController viewControllers] objectAtIndex:0] != self) {
    UIButton *btnBack = [UIButton buttonWithType:UIButtonTypeCustom];
    btnBack.frame = CGRectMake(0,0,38,30);
    [btnBack setBackgroundImage:[UIImage imageNamed:@"NavigationBarBackButton"] forState:UIControlStateNormal];
    [btnBack addTarget:self.navigationController action:@selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *leftBtn = [[UIBarButtonItem alloc] initWithCustomView:btnBack];
    [self.navigationItem setLeftBarButtonItem:leftBtn];
}
查看更多
登录 后发表回答