自定义导航栏返回按钮

8
在我的应用程序中有许多带有UINavigationControllers的UIViewControllers。在UINavigationBar上必须有一个“返回”按钮和一个“主页”UIButton。所有这些都很好地工作。但是,我的一些UIViewControllers具有较长的名称,有时剩下的空间太小了。我试图用自定义的“Back”替换“返回”按钮的原始标签(它显示前一个视图的标题),但无论我尝试什么都不起作用:
// Title didn't change
[self.navigationItem.backBarButtonItem setTitle:@"Back"];

// Action didn't set, no response from button ( button didn't do anything )
[self.navigationItem.leftBarButtonItem
   setAction:self.navigationItem.backBarButtonItem.action];

我需要“返回”按钮的样式像这个问题中所示:在iPhone导航栏上绘制自定义后退按钮


你引用的问题中提供的答案不够吗? - eric.mitchell
它设置(更改)了先前视图的标题。 - SentineL
它并不是解决方案。那个方法没有保存按钮的形状。 - SentineL
在iOS 7之前,没有官方API可以实现您想要的功能。关于iOS 7我不确定。 - nielsbot
6个回答

50

尝试以下方法。这一定会起作用:

- (void)viewDidLoad {
    [super viewDidLoad];

    UIImage *buttonImage = [UIImage imageNamed:@"back.png"];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:buttonImage forState:UIControlStateNormal];
    button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
    [button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    self.navigationItem.leftBarButtonItem = customBarItem;
    [customBarItem release];
}

- (void)back {
    [self.navigationController popViewControllerAnimated:YES];
}

确保你的资源文件夹中有一张大小与导航栏返回按钮相同的按钮图片,并将其命名为back.png

如果需要任何其他帮助,请随时联系。


我发现,你可以通过为高亮状态设置图像来使自定义返回按钮与iOS原生返回按钮无法区分,就像这样:[button setImage:highlightedButtonImage forState:UIControlStateHighlighted]; - Omri Gazitt
为什么我用这段代码不能给自定义返回按钮添加标题? [button setTitle:@"Back" forState:UIControlStateNormal]; - ArVan
导航栏具有 UIBarButton 类型的按钮。您可以根据需要创建自定义内容的 UIBarButton 项或创建标准系统项。 - Anil Kothari
实际上,我正在使用您上面的代码,并且有这一行[button setImage:buttonImage forState:UIControlStateNormal]; 我以为我可以在后面添加[button setTitle:@"Back" forState:UIControlStateNormal];,然后它会起作用,但是它没有... - ArVan
1
这种方法的问题在于,您没有自定义返回按钮,而是添加了一个“leftBarButtonItem”,这并不是同一件事。 - quickthyme

7

目标: 将UINavigationBar上所有返回按钮自定义为白色图标。

步骤: 1. 在AppDelete的 "didFinishLaunchingWithOptions" 方法中:

UIImage *backBtnIcon = [UIImage imageNamed:@"navBackBtn"];

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    [UINavigationBar appearance].tintColor = [UIColor whiteColor];
    [UINavigationBar appearance].backIndicatorImage = backBtnIcon;
    [UINavigationBar appearance].backIndicatorTransitionMaskImage = backBtnIcon;
}else{

    UIImage *backButtonImage = [backBtnIcon resizableImageWithCapInsets:UIEdgeInsetsMake(0, backBtnIcon.size.width - 1, 0, 0)];
    [[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage  forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

    [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -backButtonImage.size.height*2) forBarMetrics:UIBarMetricsDefault];
}

2. 在普通的超级ViewController类的"viewDidLoad"方法中:

 if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
        UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@""
                                                                     style:UIBarButtonItemStylePlain
                                                                    target:nil
                                                                    action:nil];
        [self.navigationItem setBackBarButtonItem:backItem];
    }else{
        //do nothing
    }

6
尝试这个。
UIBarButtonItem *backBarBtnItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:self action:@selector(popViewController)];
[self.navigationItem setBackBarButtonItem:backBarBtnItem];

- (void)popViewController
{
    [self.navigationController popViewControllerAnimated:YES];
}

那个不起作用。我可以删除通常的返回按钮并添加自己的,但如何使它的形状像通常的一样? - SentineL
你需要添加一个自定义按钮,具有那个形状的图像...[[UIBarButtonItem alloc] initWithCustomView:customButton]; - Mihir Mehta
那是一个有点野蛮的代码,但我猜没有其他解决方案...所以,让我们暂时成为野蛮人吧 :) 无论如何感谢您的回应。 - SentineL

2

如果您像我一样到处都在这样做,最好实现Anil的解决方案作为一个类别:

@interface UIViewController (CustomBackButton)

- (void) setCustomBackButton;
- (void) back;

@end

@implementation UIViewController (CustomBackButton)

- (void) setCustomBackButton
{
    UIImage *buttonImage = [UIImage imageNamed:@"back.png"];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:buttonImage forState:UIControlStateNormal];
    button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
    [button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    self.navigationItem.leftBarButtonItem = customBarItem;
}

- (void) back
{
    [self.navigationController popViewControllerAnimated:YES];
}

@end

1
更简单地说:
UIBarButtonItem *barBtnItem = 
  [[UIBarButtonItem alloc]initWithTitle:@"Indietro"
                                  style:UIBarButtonItemStyleBordered
                                 target:self
                                 action:@selector(pop)];
[barBtnItem setTintColor:[UIColor whiteColor]];
self.navigationItem.leftBarButtonItem = barBtnItem;

0
假设您有两个控制器 - Controller1和Controller2。 Controller2是从Controller1推出的。因此,在从Controller1将Controller2推入navigationController之前
Controller2 *controller2 = [[[Controller2 alloc]  init]autorelease];
self.navigationItem.hidesBackButton = YES;   

现在,在Controller2的viewDidLoad:方法中,添加以下代码片段。
UIBarButtonItem *backBarButtonItem =[[[UIBarButtonItem alloc]initWithTitle:@"Back" style:UIBarButtonItemStyleBordered target:self action:@selector(goBackToAllPets:)]autorelease];
self.navigationItem.leftBarButtonItem = backBarButtonItem;

在 backButtonClicked 方法中,您可以执行所需的检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接