繁体   English   中英

UINavigationController中的自定义后退按钮

[英]Custom back button in 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添加到视图层次结构,可以加倍检查是否正确创建了按钮backButton 它显示正常。
  2. 在同一方法中,更改了navigationItemtitle属性并确认它更改(按预期)我的后退按钮的内容。

谁能发现我做错了什么? 有没有人成功使用自定义图像作为UINavigationController的后退按钮?

从iOS 5开始,这很简单:

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

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

我将从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];
}

就这样。 现在到处都有一个图像后退按钮。 没有边界。 请享用!

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

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

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

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

SWIFT代码

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

令人困惑的backBarButtonItem不是你想要的。

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

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)

我认为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 

请在此处查看此答案: 如何使用UINavigationController的自定义视图创建backBarButtomItem

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

正如@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

只需创建一个UIBarButtonItem而不是嵌入式UIButtonUIBarButtonItem 工作良好!

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

self.navigationItem.backBarButtonItem = backButton; 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM