UINavigationBar自定义返回按钮没有标题

我如何自定义导航返回按钮在iOS 7及以上没有标题?(即只使用箭头)

self.navigationItem.leftBarButtonItem = self.editButtonItem;

我只是想知道它们是否有self。backbuttonitem;

像这样的东西?

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

你不能以你想要的方式访问导航backButtonItem,你需要创建自己的返回按钮,如下所示:

- (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];
}

编辑:2014-04-09:当我获得声誉时,我感到抱歉,因为我不再使用这个技巧了。我推荐凯尔的答案。还要注意,__ABC1的self并不是返回按钮显示的视图控制器,而是要返回的前一个视图控制器。

如果之前的视图控制器不需要标题文本,只需用空白字符串填充标题;

self.navigationItem.title = @"";
[self.navigationController pushViewController:viewController animated:YES];

这将防止在被推送的视图控制器上显示带雪佛龙的“返回”。

编辑:即使你使用非空白标题文本,在viewWillAppear:中设置前一个视图控制器的标题也可以工作,除非当视图控制器弹出时,标题会闪烁。我认为“推特应用程序”似乎做了更微妙的hack来避免闪烁。

其实很简单,我是这么做的:

Objective - C

// Set this in every view controller so that the back button displays back instead of the root view controller name
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];

斯威夫特2

self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)

斯威夫特3

self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

把这一行放到推送到堆栈的视图控制器中(之前的视图控制器)。新按下的视图控制器返回按钮现在将显示你为initWithTitle所放的任何东西,在本例中是一个空字符串。

iOS6的简单破解也适用于iOS7:

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

<强>编辑: 不要使用这种方法。

iOS7有新的界面规则,所以当你推送一个UIView时,最好至少保持后退箭头。 通过编程方式更改“返回”文本非常容易。只需在推送视图(如果你使用的是StoryBoards,则为prepareForSegue)之前添加以下代码:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
self.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc] initWithTitle:@"NEW TITLE" style:UIBarButtonItemStylePlain target:nil action:nil];
}
这将改变默认的“后退”文本,但将保持iOS7风格的后退箭头。 你也可以在推送视图之前改变后退箭头的颜色:

- (void)viewDidLoad{
//NavBar background color:
self.navigationController.navigationBar.barTintColor=[UIColor redColor];
//NavBar tint color for elements:
self.navigationController.navigationBar.tintColor=[UIColor whiteColor];
}

希望这对你有所帮助!

这在iOS6和ios7上都很有效

Xamarin (c#)选项

var buttonStyleItems = UIBarButtonItem.AppearanceWhenContainedIn(typeof(SettingsNavigationController));
buttonStyleItems.SetBackButtonTitlePositionAdjustment(new UIOffset(-1000, -1000), UIBarMetrics.Default);

objective - c选项

[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-1000, -1000) forBarMetrics:UIBarMetricsDefault];

在你的第一个ViewController的prepareForSegue:方法中,你设置视图标题为@"",所以当下一个视图被推送时,它将显示前一个ViewController标题为@""。

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
self.navigationItem.title = @" ";
}

唯一的问题是,当你点击返回按钮时,你之前的视图将没有标题,所以你可以在viewWillAppear上再次添加它:

-(void)viewWillAppear:(BOOL)animated{
self.navigationItem.title = @"First View Title";
}

我不太喜欢这个解决方案,但它是可行的,我没有找到其他方法来做到这一点。

我从iOS 5开始就一直在使用这个解决方案,没有任何问题。我在视图控制器中调用了一个实用函数。你需要在viewDidLoad或之后的任何点中做。

void updateBackButtonTextForViewController(UIViewController *viewController, NSString *text)
{
if(! viewController.navigationItem.backBarButtonItem)
{
viewController.navigationItem.backBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:text
style:UIBarButtonItemStylePlain
target:nil action:nil];
}
else
{
viewController.navigationItem.backBarButtonItem.title = text;
}
}

在某些情况下,导航项可能已经存在,在其他情况下需要创建它。这在不影响导航项标题的情况下解释了这两种情况。它允许你通过简单地传入@""来删除标题。

这是有效的,但它会删除前一项的标题,即使你弹出回到它:

self.navigationController.navigationBar.topItem.title = @"";

只需要在推送视图控制器的viewDidLoad上设置这个属性。

你可以用这个。这对我来说是完美的,只要添加一个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;
}

我找到了一个简单的方法,让我的返回按钮与iOS单箭头。

让我们假设你有一个导航控制器从ViewB到ViewA。在IB中,选择ViewA的导航栏,你应该看到这些选项:标题,提示和返回按钮。

ViewA导航栏选项

ViewA导航栏选项

诀窍是在以前的视图控制器(view A)的选项中选择你的命运视图控制器返回按钮标题(ViewB)。如果你不填写“返回按钮”选项,iOS将自动设置标题“返回”,带有以前的视图控制器的标题。因此,您需要用一个空格填充这个选项。

在“返回按钮”选项中填充空格

填充空格

结果:

The Result: .

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

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

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

我在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"]]];

只是更新我使用矢量图标

要添加到上面的托马斯·C的回答,有时只添加一个空格是不行的,你必须继续添加空格。

空栏按钮

当你看到“导航项”下的“栏按钮项-”时,你就知道你成功了。这是在文档大纲(编辑器->显示文档大纲)。一旦你看到上面的图片,你可以删除一些空格,看看它是否仍然有效。

这招对我很管用

[[UIBarButtonItem appearance]
setBackButtonTitlePositionAdjustment:UIOffsetMake(-1000, -1000)
forBarMetrics:UIBarMetricsDefault];

愿一切都好!

< >强目标: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.在公共超类ViewControllerviewDidLoad方法中:

 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
}

虽然Kyle Begeman的回答完全可以做到这一点,但在每个视图控制器中都使用这段代码是相当烦人的。我最终得到了一个简单的UINavigationItem类别。小心,这里有龙!抱歉,我的意思是:

#import <objc/runtime.h>


@implementation UINavigationItem (ArrowBackButton)


static char kArrowBackButtonKey;


+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method m1 = class_getInstanceMethod(self, @selector(backBarButtonItem));
Method m2 = class_getInstanceMethod(self, @selector(arrowBackButton_backBarButtonItem));
method_exchangeImplementations(m1, m2);
});
}


- (UIBarButtonItem *)arrowBackButton_backBarButtonItem {
UIBarButtonItem *item = [self arrowBackButton_backBarButtonItem];
if (item) {
return item;
}


item = objc_getAssociatedObject(self, &kArrowBackButtonKey);
if (!item) {
item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:NULL];
objc_setAssociatedObject(self, &kArrowBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return item;
}


@end
 // 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];


}

你可以子类化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

只用一张图片!

OBJ-C:

- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Icon-Back"]
style:UIBarButtonItemStylePlain
target:self.navigationController
action:@selector(popViewControllerAnimated:)];
self.navigationItem.leftBarButtonItem = backButton;
}

斯威夫特4:

let backBTN = UIBarButtonItem(image: UIImage(named: "Back"),
style: .plain,
target: navigationController,
action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItem = backBTN
navigationController?.interactivePopGestureRecognizer?.delegate = self

Icon-Back.png

Icon-Back

Icon-Back@2x.png

Icon-Back@2x

Icon-Back@3x.png

Icon-Back@23x

你不需要做什么。你可以通过故事板本身来实现同样的效果。

只要到根导航控制器,并给一个空间。记住,返回按钮不是指向你想要的没有标题的控制器,而是指向根导航控制器。

如下图。这适用于iOS 7和iOS 8

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// Custom initialization
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];


}
return self;
}

就像Kyle Begeman所做的那样,在根视图控制器中添加上面的代码。所有子视图控制器都会被应用。此外,在initWithCoder:方法中添加这个,你可以在xib、storyboard或基于代码的方法中应用根视图控制器的样式。

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

这里是使用方法swizzling的方法,只需创建新的扩展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
}
}
}

将标题设置为空

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;

唯一对我有效的方法是:

navigationController?.navigationBar.backItem?.title = ""

更新:

当我改变segue动画标志为真(之前是假的),唯一适合我的方法是:

navigationController?.navigationBar.topItem?.title = ""

如果你有两个ViewController(FirstVC, seconddvc)嵌入在导航控制器中,你想在seconddvc中只有后退箭头。

你可以试试这个 在FirstVC的ViewDidLoad

override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
}

然后当你推到seconddvc,你会看到只有后退箭头

如果你设置了导航栏的tintColor,添加一个没有标题的自定义后退按钮图像,该图像的tintColor将反映图像的颜色。请点击苹果文档链接。

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/UIKitUICatalog/index.html#//apple_ref/doc/uid/TP40012857-UIView-SW7

UINavigationItem *navItem = [[UINavigationItem alloc] init];
navBar.tintColor = self.tintColor;


UIImage *myImage = [UIImage imageNamed:@"left_arrow.png"];
myImage = [myImage              imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];


UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithImage:myImage style:UIBarButtonItemStylePlain target:self action:@selector(cancelButtonFunction:)];
navItem.leftBarButtonItem = leftButton;


navBar.items = @[ navItem ];

这就是我怎么做的,也是最简单,最有效,最清晰的方法。

如果嵌入在Navigation Controller上,则有效

斯威夫特3

viewDidLoad中,我将此添加到视图控制器中,您希望返回按钮只是箭头。

if let topItem = self.navigationController?.navigationBar.topItem {
topItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}

这个和@Kyle Begeman的回答的不同之处在于你在视图控制器上调用这个你想让后退按钮只是箭头,而不是在push stack视图控制器上。

  1. 添加新的UIBarButtonItem到左边的UINavigationItem
  2. 改变UIBarButtonItem的使用方式
  3. 现在,点击UINavigationItem,并从outlets滑动barBackButtonItem到左UIBarButtonItem

enter image description here

你可以把这个类别放在AppDelegate中。m文件。 从UINavigation的所有默认后退按钮中移除文本。只有箭头“<”或设置自定义图像如果你需要

objective - c:

...

@end

@implementation UINavigationItem (Extension)


- (UIBarButtonItem *)backBarButtonItem {


return [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}


@end

设置返回按钮项目标题为空字符串。

[self.navigationController.navigationBar。backItem setTitle: @ ");

我写了一个扩展,使这更容易:

extension UIViewController {


/// Convenience for setting the back button, which will be used on any view controller that this one pushes onto the stack
@objc var backButtonTitle: String? {
get {
return navigationItem.backBarButtonItem?.title
}
set {
if let existingBackBarButtonItem = navigationItem.backBarButtonItem {
existingBackBarButtonItem.title = newValue
}
else {
let newNavigationItem = UIBarButtonItem(title: newValue, style:.plain, target: nil, action: nil)
navigationItem.backBarButtonItem = newNavigationItem
}
}
}


}

你可以在viewWillDisappear上将当前ViewController的标题改为@"",当它即将再次显示时,将标题重新设置为之前的标题。

-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.title = @"Previous Title";
}


-(void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.title = @"";
}

斯威夫特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. 创建一个通用函数,如下所示:

    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)
    
  • backItem.title = ""改为使用topItem.title = ""
  • 设置navigationItem.hidesBackButton = true &navigationItem.leftBarButtonItem将失去后退手势
  • 记住,我们必须创建2个back映像的实例

我的解决方案将改变图像&保持背部姿势:

navigationController?.navigationBar.backIndicatorImage = UIImage(named: "back")
navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "back")
navigationController?.navigationBar.topItem?.title = ""