如何更改导航栏上“返回”按钮的标题
Posted
技术标签:
【中文标题】如何更改导航栏上“返回”按钮的标题【英文标题】:How do I change the title of the "back" button on a Navigation Bar 【发布时间】:2010-11-29 18:40:37 【问题描述】:当前左栏按钮默认值是加载当前视图的标题,即按下按钮时显示的视图(后退按钮)。
我想将按钮上显示的文本更改为其他内容。
我尝试将以下代码行放在视图控制器的 viewDidLoad 方法中,但它似乎不起作用。
self.navigationItem.leftBarButtonItem.title = @"Log Out";
我该怎么办?
谢谢。
【问题讨论】:
请检查 ios 11+ solution - 不需要再次创建后退按钮。 【参考方案1】:这应该放在调用标题为“NewTitle”的 ViewController 的方法中。 就在 push 或 popViewController 语句之前。
UIBarButtonItem *newBackButton =
[[UIBarButtonItem alloc] initWithTitle:@"NewTitle"
style:UIBarButtonItemStyleBordered
target:nil
action:nil];
[[self navigationItem] setBackBarButtonItem:newBackButton];
[newBackButton release];
【讨论】:
在子视图控制器中,从子视图控制器调用这个将不起作用。您必须在子视图控制器中从父视图控制器调用它。 要更改我的第三级视图控制器的后退按钮(第二次推送),我必须使用以下行而不是上面的答案: [[self.parentViewController navigationItem] setBackBarButtonItem: newBackButton];我做错了吗? Jordan 说他“[添加]了更清晰的代码放置位置。”这里更加清晰:将它放在第一个(又名父级)控制器中,紧接在调用第二个(又名子)控制器之前。 你可以创建一个自定义的BaseViewController并将其放入-viewDidLoad:
您不必在推送或弹出之前执行此操作。您可以在 viewDidLoad 或 loadView 或您为该视图设置标题和其他属性的任何其他位置执行此操作。维克多·博格丹(Victor Bogdan)的回答更清楚,恕我直言。【参考方案2】:
在 ChildVC 中,这对我有用...
self.navigationController.navigationBar.topItem.title = @"Back";
也可以在 Swift 中使用!
self.navigationController!.navigationBar.topItem!.title = "Back"
【讨论】:
在 Xcode 5.0.2 的 iOS 7 上测试和验证。当您返回时,这会将前一个屏幕的标题更改为“返回”。 最简单的解决方案。适用于 iOS 6 和 7。放入基础 UIViewController 并完成。比 IB 解决方案或推送 vc 中的设置要好得多。 它改变了前一个视图控制器的标题,这就是这个解决方案的问题 @Nikita,您可以在 viewWillDisappear 中重新设置磁贴【参考方案3】:这是 backBarButtonItem 的文档:
"当此导航项紧接在顶部项的下方时 堆栈,导航控制器为 此导航项的导航栏。 [...] 如果你想 为后退按钮指定自定义图像或标题,您可以指定一个 自定义栏按钮项(带有您的自定义标题或图像)到此 属性。”
视图控制器A(“父”视图控制器):
self.title = @"Really Long Title";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Short" style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
当任何其他视图控制器 B 在导航堆栈的顶部,并且 A 在它的正下方时,B 的后退按钮将有标题“短”。
【讨论】:
棘手的部分是您需要在父视图控制器而不是子视图中设置后退按钮。浪费了一个小时才弄明白。【参考方案4】:在使用情节提要的 Xcode 4.5 中,到目前为止,当后退按钮的值不必动态更改时,我发现的最简单的解决方案是使用与视图控制器的导航项关联的“后退按钮”字段您希望“返回”按钮对其说出其他内容。
例如在下面的屏幕截图中,我希望我推动的视图控制器的后退按钮具有“后退”作为后退按钮的标题。
当然,如果您需要后退按钮每次都说些稍有不同的内容,这将不起作用……这里有所有其他解决方案。
【讨论】:
最初的问题没有说明任何关于使用情节提要的内容,所以这绝对是好的不是公认的答案,但是正确的解决方案是基于情节提要的开发。 【参考方案5】:我知道,这个问题很老了,但我找到了一个不错的解决方案。
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] init];
barButton.title = @"Custom Title";
self.navigationController.navigationBar.topItem.backBarButtonItem = barButton;
从 childView 工作!使用 iOS 7 测试。
【讨论】:
这似乎只适用于一个级别。对我来说,它不适合一个孩子的孩子。 iOS 8。【参考方案6】:也许我过于简单了,但从 Apple 的文档来看,措辞是:
如果任何一个视图控制器都没有指定自定义条形按钮项,则使用默认后退按钮并将其标题设置为标题的值前一个视图控制器的属性——也就是说,视图控制器在堆栈的下一层。
上面标记为正确的解决方案设置了父控制器的默认按钮项。这是正确的答案,但我通过在将新控制器推送到 NavigationController 堆栈之前更改 UIViewController 的 self.title
属性来解决问题。
这会自动更新下一个控制器上的后退按钮的标题,只要您将self.title
设置回它应该在viewWillAppear
中的位置,我看不出这种方法会导致太多问题。
【讨论】:
【参考方案7】:这对我来说效果更好。试试看:
self.navigationController.navigationBar.topItem.backBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
【讨论】:
【参考方案8】:在 Swift/iOS8 中,以下对我有用:
let backButton = UIBarButtonItem(
title: "Back Button Text",
style: UIBarButtonItemStyle.Bordered,
target: nil,
action: nil
);
self.navigationController.navigationBar.topItem.backBarButtonItem = backButton;
转自 Felipe 的回答。
【讨论】:
swift 1.1 语法是self.navigationController?.navigationBar.topItem?.backBarButtonItem
样式应该是 UIBarButtonItemStyle.Plain
谢谢。这是一个多么可悲的 API。和一般的 UIKit 的代表。在 iOS 中的导航栏和状态栏之间,我们仍然为这个该死的平台开发真是一个奇迹。感谢 Baby jesus 的 Stack Overflow 及其贡献者!
@Wobmle:你应该为 android 开发几个月;)【参考方案9】:
好的,方法就是这样。如果您有一个“第一个”视图控制器,并且您通过按下按钮等“第二个”导航另一个视图控制器,您需要做一些工作。 首先,您需要像这样在“第二个”视图控制器的 ViewDidLoad 方法中创建一个 BarButtonItem;
UIBarButtonItem *btnBack = [[UIBarButtonItem alloc]
initWithTitle:@"Back"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(OnClick_btnBack:)];
self.navigationItem.leftBarButtonItem = btnBack;
[btnBack release];
完成此操作后,您需要像这样在同一个 .m 文件中写入“btnBack”操作的代码;
-(IBAction)OnClick_btnBack:(id)sender
[self.navigationController popViewControllerAnimated:YES];
//[self.navigationController pushViewController:self.navigationController.parentViewController animated:YES];
就是这样。
【讨论】:
leftBarButtonItem
没有backBarButtonItem
的外观,如果这在应用程序设计中很重要的话。
在已发布的解决方案中(非常感谢),这个似乎可行,尽管正如 Alex 上面所说,左栏按钮看起来不像后栏项目。我怎样才能让它看起来像一个后栏项目???【参考方案10】:
我有一个标题很长的父视图控制器。这导致后退按钮文本渗入子视图控制器的标题。
在尝试了一堆不同的解决方案之后,这就是我最终要做的事情(扩展 @john.k.doe 方法):
使用 Xcode 7.2、Swift 2
-
在 Storyboard 中,将
Navigation Item
添加到 Parent 视图控制器场景(不是子 VC)
-
在新
Navigation Item
的Attributes Inspector
上,在Back Button
字段中输入space
字符。稍后会详细介绍。
-
在 Parent 视图控制器中,添加以下代码:
sn-p:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
switch segue.destinationViewController
case is ChildViewController:
navigationItem.backBarButtonItem?.title = ""
default:
navigationItem.backBarButtonItem?.title = "Full Parent Title"
说明:
后退按钮属于父视图控制器。 Navigation Item
为您提供返回按钮的句柄,因此您可以在代码或情节提要中设置标题。
注意:
如果您将Navigation Item
Back Button
文本保留为默认空字符串,则返回按钮标题将变为“返回”。
其他方法也行,为什么要使用这个?:
虽然可以覆盖子视图控制器上的后退按钮标题,但要处理它是一个挑战,直到它已经在屏幕上短暂闪烁。
一些方法构建一个新的后退按钮并覆盖现有的。我确信它有效,并且在某些用例中可能是必要的。但我更喜欢尽可能利用现有的 API。
更改父视图控制器的title
在某些情况下是最快的解决方案。但是,这会更改父标题,因此您必须管理状态。 Tab Bar Controller
也会让事情变得一团糟,因为标题更改会导致 Tab Bar Item
标题的副作用。
【讨论】:
【参考方案11】:对于那些使用故事板的人,只需选择父视图控制器框架(不是持有目标视图的那个)视图控制器框架(确保您在导航栏上单击右键,然后打开属性检查器,您将在其中找到三个表单输入。第三个“返回按钮”是我们正在寻找的。p>
【讨论】:
如果您不关心本地化,这是最好的解决方案。【参考方案12】:Swift 版本:
在您的子 ViewController 中:
override func viewWillAppear(animated: Bool)
super.viewWillAppear(animated)
self.navigationController?.navigationBar.backItem?.title = "TEXT"
【讨论】:
这实际上会将堆栈中前一个视图控制器的标题更改为“TEXT”,这不太理想。【参考方案13】:这是另一种方法。
在您的父视图控制器中,实现以下方法:
- (void) setBackBarButtonItemTitle:(NSString *)newTitle
self.navigationItem.backBarButtonItem.title = newTitle;
在您的子视图控制器中,当您想要更改标题时,这将起作用:
NSArray *viewControllerArray = [self.navigationController viewControllers];
int parentViewControllerIndex = [viewControllerArray count] - 2;
[[viewControllerArray objectAtIndex:parentViewControllerIndex] setBackBarButtonItemTitle:@"New Title"];
我一直无法让parentViewController
属性工作:
[(ParentViewController *)(self.navigationController.parentViewController) setBackBarButtonItemTitle:@"New Title"];
我不知道这是一个错误还是我没有正确使用它。但是在viewControllers
数组中抓取倒数第二个视图控制器指向父视图控制器,我可以使用该引用正确调用父方法。
【讨论】:
【参考方案14】:好的。我个人讨厌所有这些选择。所以我想出了自己的。
根据我看到的信息。看起来上一个视图控制器控制着它自己的“返回”按钮,该按钮将显示在推送的视图控制器上。
我已经为想要更改后退按钮的控制器上的 navigationItem 创建了一个延迟加载方法。
我是一个邀请买家控制器
Invite Buyer 是默认设置的文本。
但后退按钮需要邀请
这是我用来创建后退按钮的代码。
我将此代码放在控制器的实现 (.m) 文件的顶部,它会自动覆盖超级的方法。
- (UINavigationItem *)navigationItem
UINavigationItem *item = [super navigationItem];
if (item != nil && item.backBarButtonItem == nil)
item.backBarButtonItem = [[[UIBarButtonItem alloc] init] autorelease];
item.backBarButtonItem.title = @"Invite";
return item;
我觉得这是一种更优雅的方式来实现这一点。
我将这段代码放在一个地方,它会在需要时自动填充。
无需在每次推送之前调用代码。
希望对你有帮助
【讨论】:
【参考方案15】:对于斯威夫特:
// Rename back button
let backButton = UIBarButtonItem(
title: "Back",
style: UIBarButtonItemStyle.Plain, // Note: .Bordered is deprecated
target: nil,
action: nil
)
self.navigationController!.navigationBar.topItem!.backBarButtonItem = backButton
【讨论】:
【参考方案16】:UIBarButtonItem *btnBack = [[UIBarButtonItem alloc]
initWithTitle:@"Back"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(OnClick_btnBack:)];
self.navigationItem.leftBarButtonItem = btnBack;
[btnBack release];
【讨论】:
【参考方案17】:答案如下:
在viewDidAppear:animated
(不在viewDidLoad
)中执行以下操作
- (void)viewDidAppear:(BOOL)animated
[self.navigationController.navigationBar.backItem setTitle:@"anything"];
// then call the super
[super viewDidAppear:animated];
如果你想保持返回按钮的形状。
【讨论】:
不错,只是他们可以看到它更改标题。我在 viewWillAppear 中尝试过,但它不起作用。【参考方案18】:这里解释的解决方案都不适合我。所以我所做的就是通过以下方式从我来自的场景中删除标题:
self.title = @"";
所以当新场景出现时,后面的文字不会出现。
我绝对同意这根本不是一个明确的解决方案,但是有效,并且解释的任何一个都不适合我。
【讨论】:
伙计,我得告诉你,现在是 2017 年,处理后退按钮仍然很痛苦。你的方法对我有用,虽然我想要“取消”这个词,但我最终得到了“ 【参考方案19】:我发现最好将导航堆栈中当前视图控制器的标题更改为所需的后退按钮文本,然后再推送到下一个视图控制器。
例如
self.navigationItem.title = @"Desired back button text";
[self.navigationController pushViewController:QAVC animated:NO];
然后在 viewDidAppear 中将标题设置回原始 VC 所需的标题。瞧!
【讨论】:
【参考方案20】:我发现,更改后退按钮名称的最简单方法是将视图控制器标题设置为后退按钮的标题,然后将视图控制器导航项中的 titleView 替换为自定义标签用它的真名。
像这样:
CustomViewController.m
@implementation CustomViewController
- (NSString*)title
return @"Back Button Title";
- (void)viewDidLoad
[super viewDidLoad];
UILabel* customTitleView = [[UILabel alloc] initWithFrame:CGRectZero];
customTitleView.text = @"Navigation Bar Title";
customTitleView.font = [UIFont boldSystemFontOfSize:20];
customTitleView.backgroundColor = [UIColor clearColor];
customTitleView.textColor = [UIColor whiteColor];
customTitleView.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
customTitleView.shadowOffset = CGSizeMake(0, -1);
[customTitleView sizeToFit];
self.navigationItem.titleView = [customTitleView autorelease];
@end
这将使 UINavigationBar 中的标题看起来像是原生的。使视图控制器能够具有单独的标题和后退按钮标题。
在视图控制器 A 和 B 的情况下,A 负责告诉 B 显示时它的后退按钮应该是什么样子。
编辑:这也保持了后退按钮的原生外观(左箭头栏按钮项)。
【讨论】:
【参考方案21】:此代码也有效。把它放在导航控制器的根控制器上:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
【讨论】:
【参考方案22】:我是 iOS 新手,但我将提供非常简单的答案,即覆盖导航控制器类。 我简单地覆盖了 push 和 pop 方法并保存了前一个视图控制器的标题。抱歉粘贴到 js 块中。有点困惑如何在普通代码块中过去。
#import "MyCustomNavController.h"
@implementation MyCustomNavController
NSString *_savedTitle;
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated withBackBtnTitle:(NSString *)title
_savedTitle = self.topViewController.title;
self.topViewController.title = title;
[super pushViewController:viewController animated:animated];
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
[self.viewControllers objectAtIndex:self.viewControllers.count - 2].title = _savedTitle;
return [super popViewControllerAnimated:animated];
@end
【讨论】:
【参考方案23】:self.navigationController.navigationBar.backItem.title = @"TEXT";
在 Swift 中:
self.navigationController?.navigationBar.backItem?.title = "TEXT"
【讨论】:
【参考方案24】:self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc]
initWithTitle:@"Log out"
style:UIBarButtonItemStyleDone
target:nil
action:nil] autorelease];
您可以将它放在父控制器的代码中的任意位置,这样您就可以为不同的子视图设置不同的后退按钮。
【讨论】:
【参考方案25】:大多数解决方案会在添加具有所需标题的常用按钮时取消 BackButton 的原始样式(左箭头栏按钮)。 所以要保持原来的风格有两种方法: 第一:使用我不喜欢做的无证按钮样式(110或类似的东西)。但是,如果您愿意,可以在 *** 上找到如何操作。 第二:使用我Trenskow的想法。我喜欢它,我使用它有点改变。 我决定以以下方式保留原始标题,而不是覆盖 - (NSString*)title(这允许我使用 nib 的标题以及在推送状态下给定的标题)。
- (void)viewDidLoad
[super viewDidLoad];
static NSString * backButtonTitle=@"Back"; //or whatever u want
if (![self.title isEqualToString:backButtonTitle])
UILabel* customTitleView = [[UILabel alloc] initWithFrame:CGRectZero];
customTitleView.text = self.title; // original title
customTitleView.font = [UIFont boldSystemFontOfSize:20];
customTitleView.backgroundColor = [UIColor clearColor];
customTitleView.textColor = [UIColor whiteColor];
customTitleView.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
customTitleView.shadowOffset = CGSizeMake(0, -1);
[customTitleView sizeToFit];
self.navigationItem.titleView = [customTitleView autorelease];
self.title = backButtonTitle;
这个解决方案效果很好,看起来很原生。此外,如果在 viewDidLoad 方法中使用它,它会阻止执行超过 1 次。 我也尝试过 Jessedc 的解决方案,但看起来很糟糕。它会导致用户标题栏即时从原始更改为 BackButton 的所需并返回。
【讨论】:
【参考方案26】:这对我来说是以前发布的答案的“简化”版本。
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] init];
backButton.title = @"Go Back";
self.navigationItem.backBarButtonItem = backButton;
请记住将代码放在父视图控制器(例如具有您的表格视图或 UITableViewController 的视图)中,不是子视图或详细视图(例如 UIViewController)。
您可以像这样轻松地本地化后退按钮字符串:
backButton.title = NSLocalizedString(@"Back Title", nil);
【讨论】:
【参考方案27】:根据document的UINavigationBar
>backItem
如果最顶部导航项的 leftBarButtonItem 属性是 nil,导航栏显示一个返回按钮,其标题是派生的 来自此属性中的项目。
但设置backItem.backBarButtonItem
在第一次viewWillAppear 中不起作用。设置topItem.backBarButtonItem
仅适用于第一次 viewWillAppear。因为navigationBar.topItem
仍然指向previousViewController.navigationItem
。在 viewWillLayoutSubviews
中,topItem
和 backItem
已更新。所以在第一次viewWillAppear
之后,我们应该设置backItem.backBarButtonItem
。
回答:无论何时何地在您当前的 viewController(顶部 viewController)中,都将 backBarButtonItem
设置为前一个 viewController 的 navigationItem
。您可以在viewWillAppear
或viewDidLoad
中使用此代码。详细分析请查看我的博文iOS Set Navigation Bar Back Button Title。
NSArray *viewControllerArray = [self.navigationController viewControllers];
// get index of the previous ViewContoller
long previousIndex = [viewControllerArray indexOfObject:self] - 1;
if (previousIndex >= 0)
UIViewController *previous = [viewControllerArray objectAtIndex:previousIndex];
previous.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:backButtonTitle
style:UIBarButtonItemStylePlain
target:self
action:nil];
【讨论】:
根据你的博文: override func viewWillLayoutSubviews() super.viewWillLayoutSubviews() let customBackButton = UIBarButtonItem(title: "BackTitle", style: .bordered, target: nil, action: nil) self .navigationController?.navigationBar.backItem?.backBarButtonItem = customBackButton 【参考方案28】:我们有两个 VC 的 A 和 B。
如果要在 B 中更改标题,请在 A 中编写此代码
- (IBAction)goToBViewController:(UIButton *)sender
BViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"VC"];
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Your title here"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
[[self navigationItem] setBackBarButtonItem:newBackButton];
[self.navigationController pushViewController:vc animated:NO];
Swift 4.1 Xcode 9.4
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "VC"])
let newBackButton = UIBarButtonItem.init(title: "Your title here", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
navigationController?.navigationBar.topItem?.backBarButtonItem = newBackButton
navigationController?.pushViewController(secondViewController!, animated: true)
【讨论】:
【参考方案29】:Stan 的回答是最好的。但它也有一个问题,当您使用带有标签栏的控制器并更改控制器的标题时,您也可以更改标签栏的标题。所以最好的答案是只更改 view_controller.navigationItem.title 并使用 view_controller.navigationItem .title 在函数中。 答案在这里:(使用 ARC 并将它们添加到视图的 viewDidLoad)
static NSString * back_button_title=@"Back"; //or whatever u want
if (![view_controller.navigationItem.title isEqualToString:back_button_title])
UILabel* custom_title_view = [[UILabel alloc] initWithFrame:CGRectZero];
custom_title_view.text = view_controller.navigationItem.title; // original title
custom_title_view.font = [UIFont boldSystemFontOfSize:20];
custom_title_view.backgroundColor = [UIColor clearColor];
custom_title_view.textColor = [UIColor whiteColor];
custom_title_view.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
custom_title_view.shadowOffset = CGSizeMake(0, -1);
[custom_title_view sizeToFit];
view_controller.navigationItem.titleView = custom_title_view;
view_controller.navigationItem.title = back_button_title;
在我自己的使用中,我把它做成了这样的一个函数,只要在viewDidLoad中用一行代码就可以了。
+ (void)makeSubViewHaveBackButton:(UIViewController*) view_controller
static NSString * back_button_title=@"Back"; //or whatever u want
if (![view_controller.navigationItem.title isEqualToString:back_button_title])
UILabel* custom_title_view = [[UILabel alloc] initWithFrame:CGRectZero];
custom_title_view.text = view_controller.navigationItem.title; // original title
custom_title_view.font = [UIFont boldSystemFontOfSize:20];
custom_title_view.backgroundColor = [UIColor clearColor];
custom_title_view.textColor = [UIColor whiteColor];
custom_title_view.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
custom_title_view.shadowOffset = CGSizeMake(0, -1);
[custom_title_view sizeToFit];
view_controller.navigationItem.titleView = custom_title_view;
view_controller.navigationItem.title = back_button_title;
【讨论】:
【参考方案30】:如果您不仅想将返回按钮的文本更改为相同的文本并保持原来的左箭头形状,而且还想在用户单击返回按钮时做一些事情,我建议你看看我的“CustomNavigationController”。
【讨论】:
以上是关于如何更改导航栏上“返回”按钮的标题的主要内容,如果未能解决你的问题,请参考以下文章