UINavigationController中的自定义后退按钮

时间:2010-08-17 19:42:17

标签: iphone uinavigationcontroller

对于我正在开发的应用程序,我需要在导航栏中显示自定义后退按钮。我将按钮资源作为PNG图像,我正在编写此代码:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    backButton.frame = CGRectMake(0, 0, 79, 29.0);
    [backButton setImage:[UIImage imageNamed:@"button_back.png"] forState:UIControlStateNormal];
    self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease];

}

当我按下这个视图控制器时,自定义按钮没有显示,而是我得到了标准后退按钮,里面有这个视图控制器的标题。

我已经尝试过的事情:

  1. 通过将按钮backButton添加到视图层次结构中,可以加倍检查是否正确创建了按钮title。它显示正确。
  2. 在同一方法中,更改了navigationItem的{​​{1}}属性,并确认它更改了(按预期方式)我的后退按钮的内容。
  3. 有人能发现我做错了吗?是否有人使用UINavigationController

    成功使用自定义图片作为后退按钮

10 个答案:

答案 0 :(得分:18)

从iOS 5开始,这很简单:

[[UIBarButtonItem appearance]
            setBackButtonBackgroundImage:[UIImage imageNamed:@"back_button.png"]
            forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

您可以将其放置在您的应用委托中,并将背景图像设置为应用中的所有后退按钮(当然,对于该控件状态和条形指标)。

答案 1 :(得分:13)

我正在从https://stackoverflow.com/a/16831482/171933重新发布解决方案:

我在UIViewController上创建了一个简单类别:

<强>的UIViewController + ImageBackButton.h

#import <UIKit/UIKit.h>

@interface UIViewController (ImageBackButton)

- (void)setUpImageBackButton;

@end

<强>的UIViewController + ImageBackButton.m

#import "UIViewController+ImageBackButton.h"

@implementation UIViewController (ImageBackButton)

- (void)setUpImageBackButton
{
    UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 34, 26)];
    [backButton setBackgroundImage:[UIImage imageNamed:@"back_arrow.png"] forState:UIControlStateNormal];
    UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = barBackButtonItem;
    self.navigationItem.hidesBackButton = YES;
}

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

@end

现在,您需要做的只是#import UIViewController+ImageBackButton.h所有视图控制器或其他视图控制器继承的自定义基本视图控制器类并实现viewWillAppear:方法:

- (void)viewWillAppear:(BOOL)animated
{
    [self setUpImageBackButton];
}

这就是全部。现在到处都有一个图像后退按钮。没有边界。享受!

答案 2 :(得分:5)

backBarButtonItem属性按预期工作,但它将始终根据导航栏色调颜色添加其标准按钮形状和颜色。

您可以自定义文字,但不能替换图像。

正如Andrew Pouliot建议的那样,一个解决方法是改为使用leftBarButtonItem,但我坚持使用标准按钮。

答案 3 :(得分:4)

最简单的解决方案不仅仅是从故事板中设计出您想要的任何图像或颜色,只需将新动作拖到控制器上即可?

Swift Code

@IBAction func backButton(sender: AnyObject) {
    self.navigationController?.popViewControllerAnimated(true)
}

答案 4 :(得分:3)

令人困惑的backBarButtonItem并不是您想要的。

它只控制下一个视图控制器的后退按钮上的标题。您想要的是将leftBarButtonItem设置为自定义后退按钮。

答案 5 :(得分:2)

Johannes Fahrenkrug的答案有效,但背面图像会出现在非常有线的位置。

在这里,我找到了一种更好的方法将图像定位在正确的位置:

确保你有一张尺寸为24x24(@ 1x)的背面图片,我称之为backImage

当您的应用启动时执行以下代码

UINavigationBar.appearance().barTintColor = nil
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics: .Default)

答案 6 :(得分:1)

请在此处查看此答案:How to create backBarButtomItem with custom view for a UINavigationController

您只需要在推送viewController之前在navigationController 上设置backBarButtonItem属性。在viewController的backBarButtonItem方法中设置viewDidLoad属性(例如)不起作用。

答案 7 :(得分:1)

我认为ViewController本身不应该知道它的后退按钮 根据OOP,这是插入视图控制器的containerViewController的职责,例如UINavigationController。

将您的NavigationController子类化并在其中重载superClass方法,如下所示:

@implementation STONavigationController

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [super pushViewController:viewController animated:animated];
    if ([self.viewControllers indexOfObject:viewController] != NSNotFound &&
        [self.viewControllers indexOfObject:viewController] > 0){
        UIImage *img = [UIImage imageNamed:@"back-1"];
        UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, img.size.width * 2, img.size.height * 2)];
        [backButton setBackgroundImage:img forState:UIControlStateNormal];
        UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
        [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
        viewController.navigationItem.leftBarButtonItem = barBackButtonItem;
        viewController.navigationItem.hidesBackButton   = YES;
    }
}

- (void)popCurrentViewController
{
    [self popViewControllerAnimated:YES];
}

@end 

答案 8 :(得分:0)

只需在UIBarButtonItem中创建UIButton而不是嵌入式UIBarButtonItem。工作正常!

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"button_back.png"] style:UIBarButtonItemStyleBordered target:nil action:nil];

self.navigationItem.backBarButtonItem = backButton; 

答案 9 :(得分:0)

正如@pgb建议您可以使用leftBarButtonItem而不是后退按钮项。要删除默认的后退按钮项,请将其设置为nil,如下所示;

navigationController?.navigationBar.backIndicatorImage = nil
navigationController?.navigationBar.backIndicatorTransitionMaskImage = nil

let button = UIButton.init(type: .custom)
button.imageView?.contentMode = UIViewContentMode.scaleAspectFit
button.setImage(UIImage.init(named: "top_back"), for: UIControlState.normal)
button.frame = CGRect.init(x: 0, y: 0, width: 75, height: 50) 
button.addTarget(self, action: #selector(handleBackButton), for: .touchUpInside)

let barButton = UIBarButtonItem.init(customView: button)
self.navigationItem.leftBarButtonItem = barButton