自定义UINavigationBar返回按钮且不带标题

238

如何在iOS 7及以上版本中定制没有标题的返回导航按钮?(即只有箭头)

self.navigationItem.leftBarButtonItem = self.editButtonItem;

我只是想知道他们是否有任何self.backButtonItem; 或者类似这样的东西?

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
                   initWithBarButtonSystemItem:UIBarButtonSystemItemBACK 
                   target:self action:@selector(back)];

3
您可以使用 @hiroshi 的答案和导航栏 tintColor 属性来制作自定义颜色的 chevron(矢车菱形符号),而且没有任何标题。 - Dmitry Zhukov
对于那些拥有选项卡栏的用户,如果您不想要返回按钮的文本,则可以在TabBarController的**viewDidLoad()**中添加以下代码进行修复:self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) - Borzh
36个回答

7

您无法按照您想要的方式访问导航返回按钮项,您需要创建自己的返回按钮,如下所示:

- (void)loadView
{
    [super loadView];
    UIButton *backButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 44.0f, 30.0f)];
    [backButton setImage:[UIImage imageNamed:@"back.png"]  forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(popVC) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
}

当然,你需要注意的是:

此外:

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

然后我们失去了在返回按钮上发生的漂亮淡出动画。 - Kiddo
3
你需要一个遮罩来实现平滑的过渡。如果你想使用自定义图像替换默认的箭头,你还需要创建一个自定义的遮罩图像。iOS 7使用遮罩在导航转换期间使前一个屏幕的标题似乎从箭头中出现或消失。 - user
3
你将失去iOS 7的左右滑动手势! - Mazen Kasser
@user 我已经获取了自定义图像,但默认情况下色调颜色为蓝色。如何不添加色调?谢谢。 - Mazen Kasser

7

SWIFT 4

对于那些想要创建自定义返回按钮以及移除标题的人,请在推送新视图控制器的视图控制器中使用以下代码:

self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "close")
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "close")
self.navigationItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

为了更加通用,请按照以下步骤操作:
  1. Create a universal function as follows:

    func addCustomizedBackBtn(navigationController: UINavigationController?, navigationItem: UINavigationItem?) {
        navigationController?.navigationBar.backIndicatorImage = UIImage(named: "close")
        navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "close")
        navigationItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
    
  2. Then use it in the view controllers as follows:

    addCustomizedBackBtn(navigationController: self.navigationController, navigationItem: self.navigationItem)
    

6

iOS6的简单黑客方法在iOS7上也适用:

[UIBarButtonItem.appearance setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];

编辑: 不要使用这个hack。详情请见评论。


6
不要使用这个黑客方法。在64位设备上,苹果的代码存在一个漏洞,会导致模态视图无法出现,当你进行一个导航栏按钮标题偏移时。更多细节 - zh.
设备上出现了问题,模拟器上没有。 - zh.
当使用Xcode 9 / iOS 11构建时,此hack将不再起作用。"<"会出现得太低,并且在调试器中运行时会看到破损的约束条件。 - T'Pol

3

所有的答案都无法解决这个问题。在每个视图控制器中设置返回按钮标题并添加偏移量仍然会使下一个视图控制器的标题向右移动,这是不可接受的。

以下是使用方法混合的方法,只需创建新的扩展到UINavigationItem即可。

import UIKit

extension UINavigationItem {
    public override class func initialize() {

    struct Static {
        static var token: dispatch_once_t = 0
    }

    // make sure this isn't a subclass
    if self !== UINavigationItem.self {
        return
    }

    dispatch_once(&Static.token) {
        let originalSelector = Selector("backBarButtonItem")
        let swizzledSelector = #selector(UINavigationItem.noTitleBackBarButtonItem)

        let originalMethod = class_getInstanceMethod(self, originalSelector)
        let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

        let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

        if didAddMethod {
            class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

// MARK: - Method Swizzling

struct AssociatedKeys {
    static var ArrowBackButtonKey = "noTitleArrowBackButtonKey"
}

func noTitleBackBarButtonItem() -> UIBarButtonItem? {
    if let item = self.noTitleBackBarButtonItem() {
        return item
    }

    if let item = objc_getAssociatedObject(self, &AssociatedKeys.ArrowBackButtonKey) as? UIBarButtonItem {
        return item
    } else {
        let newItem = UIBarButtonItem(title: " ", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
        objc_setAssociatedObject(self, &AssociatedKeys.ArrowBackButtonKey, newItem as UIBarButtonItem?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        return newItem
    }
}
}

将返回按钮设置为“返回”一词,非常有效:self.navigationItem.backBarButtonItem.title = @“返回”; - Mike Zriel
你是什么意思啊?问题是关于如何从返回按钮中删除文本的吗? - jakub wolanski
1
许多应用程序和苹果自己的应用程序都会显示“<返回”,因此坚持标准是很好的选择。BigTakeAway和JustEat。 - Mike Zriel

3
 // add left bar button item

try this code:

- (void)viewDidLoad
{ 
    [super viewDidLoad];

   UIImage* image_back = [UIImage imageNamed:@"your_leftarrowImage.png"];
    CGRect backframe = CGRectMake(250, 9, 15,21);
    UIButton *backbutton = [[UIButton alloc] initWithFrame:backframe];
    [backbutton setBackgroundImage:image_back forState:UIControlStateNormal];
    [backbutton addTarget:self action:@selector(Btn_back:)
         forControlEvents:UIControlEventTouchUpInside];
    [backbutton setShowsTouchWhenHighlighted:YES];
    UIBarButtonItem *backbarbutton =[[UIBarButtonItem alloc] initWithCustomView:backbutton];
    self.navigationItem.leftBarButtonItem=backbarbutton;
    [backbutton release];

}
-(IBAction)Btn_back:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];

}

3

创建一个带有您想要用于根视图控制器的标题的UILabel,并将其分配给视图控制器的navigationItem.titleView

现在将标题设置为空字符串,下一个推送的视图控制器将具有没有文本的返回按钮。

self.navigationItem.titleView = titleLabel; //Assuming you've created titleLabel above
self.title = @"";

3
你可以使用这个方法。我在实践中发现只需将 UIButton 作为 UIBarButtonItem 的自定义视图即可完美运行。
尝试下面的代码:
    self.navigationItem.leftBarButtonItem=[self backButton];


- (UIBarButtonItem *)backButton
{
    UIImage *image = [UIImage imageNamed:@"back-btn.png"];
    CGRect buttonFrame = CGRectMake(0, 0, image.size.width, image.size.height);

    UIButton *button = [[UIButton alloc] initWithFrame:buttonFrame];
    [button addTarget:self action:@selector(backButtonPressed) forControlEvents:UIControlEventTouchUpInside];
    [button setImage:image forState:UIControlStateNormal];

    UIBarButtonItem *item= [[UIBarButtonItem alloc] initWithCustomView:button];

    return item;
}

3
然而,这将在iOS 7中禁用向后滑动手势。 - user102008

2
您可以继承UINavigationController类,将其设置为代理,并在代理方法navigationController:willShowViewController:animated:中设置backBarButtonItem。
@interface Custom_NavigationController : UINavigationController <UINavigationControllerDelegate>

@end

@implementation Custom_NavigationController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.delegate = self;
}

#pragma mark - UINavigationControllerDelegate

- (void)navigationController:(UINavigationController *)navigationController     willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}

@end

2
设置标题为空
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@""  style:UIBarButtonItemStyleDone target:self action:@selector(handleBack:)];
[backButton setTintColor:Color_WHITE];
[self.navigationItem setBackBarButtonItem:backButton];

更改背景图片

 UIImage *backImg = [[UIImage imageNamed:@"ic_back_white"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[UINavigationBar appearance].backIndicatorImage = backImg;
[UINavigationBar appearance].backIndicatorTransitionMaskImage = backImg;

2
我在viewDidLoad中应用了以下代码,它可以正常工作:
  // this will set the back button title
self.navigationController.navigationBar.topItem.title = @"Test";

 // this line set the back button and default icon color  

//[[self.navigationController.navigationBar.subviews lastObject] setTintColor:[UIColor blackColor]];

this line change the back default icon to your custom icon
[[self.navigationController.navigationBar.subviews lastObject] setTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"menuicon"]]];

我只是想更新一下,我使用矢量图标


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