UINavigationController“后退按钮”自定义文本?

Posted

技术标签:

【中文标题】UINavigationController“后退按钮”自定义文本?【英文标题】:UINavigationController "back button" custom text? 【发布时间】:2010-11-29 07:51:13 【问题描述】:

UINavigationController 的“后退按钮”默认显示堆栈中最后一个视图的标题。有没有办法在后退按钮中添加自定义文本?

【问题讨论】:

这项工作为我工作self.navigationController.navigationBar.topItem.title = @"Custom text"; 【参考方案1】:

来自this link:

self.navigationItem.backBarButtonItem =
   [[UIBarButtonItem alloc] initWithTitle:@"Custom Title"
            style:UIBarButtonItemStylePlain
           target:nil
           action:nil];

正如泰勒在 cmets 中所说:

不要在可见视图控制器中这样做,而是在视图中 如果你点击后退按钮,你会看到的控制器

【讨论】:

你应该releaseUIBarButtonItem 另外请注意,您需要在堆栈上一层的视图控制器中执行此操作。换句话说,不要在可见视图控制器中执行此操作,而是在您点击后退按钮时会看到的视图控制器中执行此操作。 只是为了澄清 Tyler 的评论,因为我起初不明白这一点:在视图控制器 navigationItem 中设置 backBarButtonItem 是设置将显示返回到此视图控制器的按钮。另请注意,尽管箭头按钮没有按钮样式,但此按钮无论如何都会获得箭头样式。我使用了 UIBarButtonItemStylePlain 并且仍然获得箭头按钮样式。 建议:不要假设样式,而是传递当前设置的样式。在此答案的代码中,将 UIBarButtonItemStyleBordered 替换为对属性 self.navigationItem.backBarButtonItem.style 的调用。文档:developer.apple.com/library/ios/documentation/uikit/reference/… 请注意,在 ARC 下,您必须省略 autorelease 调用。所以你有 self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Custom Title" style:UIBarButtonItemStyleBordered target:nil action:nil];【参考方案2】:

您可以在 Interface Builder 中设置文本:

选择返回按钮将返回的 ViewController 的导航项:

在实用程序面板属性检查器中,输入您的后退按钮标签:

我更喜欢这种方法,而不是像接受的答案那样在代码中设置标题。

另外请注意,您需要在视图控制器中执行此操作 堆。换句话说,不要在可见视图控制器中这样做, 但是在视图控制器中,如果您点击后退按钮,您会看到。--Tyler

【讨论】:

这是迄今为止我找到的最佳答案。 需要明确的是,这需要在视图控制器的导航项上设置,而不是在视图控制器的属性检查器本身上。 这是我找到的最佳答案。 这是最好的答案 从 Xcode 6.1.1 开始,并在 iOS 7 中运行,您原来的先前视图标题似乎仍会覆盖您在此处设置的任何后退按钮标题。如果前一个视图的标题包含超过 11 个字符的限制,那么下一个视图的后退按钮将简单地说“后退”。除了从头开始创建一个新的导航栏项目外,没有其他办法,如此处投票最多的答案所示。【参考方案3】:

我用这个:

// In the current view controller, not the one that is one level up in the stack
- (void)viewDidLoad 
    [super viewDidLoad];
    self.navigationController.navigationBar.backItem.title = @"Custom text";

【讨论】:

这几乎对我有用,但是当我单击后退按钮时,文本会在动画期间变回父级的标题:-( 这会在堆栈中向上更改控制器的后退按钮标题。它不会更改当前显示的控制器的后退按钮标题。更糟糕的是:它会将控制器的标题更改为前一个控制器! 正如其他评论者所指出的,这种方法有点站不住脚。我不建议这样做,因为 API 并不打算让您使用它。将来您可能会遇到困难的错误!【参考方案4】:

我找到了一个方便的解决方案,只需在将另一个控制器推入堆栈之前设置控制器的标题,如下所示:

self.navigationItem.title = @"Replacement Title";
[self.navigationController pushViewController:newCtrl animated:YES];

然后,确保将原始标题设置为viewWillAppear,如下所示:

-(void)viewWillAppear:(BOOL)animated

  ...
  self.navigationItem.title = @"Original Title";
  ...

这是因为UINavigationController 在按下操作期间构造后退按钮时的默认行为是使用前一个控制器的标题。

【讨论】:

这个问题是旧视图上的标题发生变化,因为它动画出来并且看起来有点naff。这里给定的解决方案似乎都没有像你想要的那样工作:-( 这在我的情况下是完美的,因为我没有在前一个屏幕上显示 NavBar,我只想从新屏幕上的后退按钮中删除 titleLabel 并且只有 iOS7 人字形箭头。因此,我可以为标题设置一个空的 NSString 文字。 推视图控制器在点击返回时引发异常【参考方案5】:

后退按钮的标题默认为前一个视图的标题,所以我使用的一个快速技巧是将以下代码放在前一个视图的 .m 文件中。

-(void)viewWillAppear:(BOOL)animated 

    // Set title
    self.navigationItem.title=@"Original Title";


-(void)viewWillDisappear:(BOOL)animated 

    // Set title
    self.navigationItem.title=@"Back";

【讨论】:

这在很多情况下都非常有效,而且非常简单......唯一的观察是,覆盖这些方法中的任何一个都需要在新方法中的某个时刻调用 super 的实现。 使用此方法,在推送动画发生之前,您会注意到父视图的标题已更改为“返回”。 (而且,有点糟糕,如果你把它移到 viewDidDisappear 方法,你会在推送之后看到切换发生......) 我喜欢这种方法,但我面临的问题是“原始标题”设置得很好,但是如果它比“返回”长,它会带有一个省略号,这一定是因为,因为视图尚未在视图层次结构中,它不会重新布局标题视图。由于动画的初始速度很快,上面@JamesBoutcher 描述的问题对我来说并不明显。事实上,我刚刚意识到我面临的问题由于动画结束缓慢而特别明显,而这正是这个问题突出的时候。 虽然***.com/questions/1441699/… 的答案感觉更像是定制而不是必要的,但这是记录在案的方式,更重要的是似乎更符合我们的意图。【参考方案6】:

在您的 init 方法中,添加以下代码:

- (id)initWithStyle:(UITableViewStyle)style 
    if(self = [super init]) 

        //...

        UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" 
                                             style:UIBarButtonItemStylePlain 
                                            target:self 
                                            action:@selector(goBack)];
        self.navigationItem.leftBarButtonItem = customBackButton;
        [customBackButton release];

        //...
    
    return self;

然后添加一个简单的方法,允许 viewcontroller 关闭:

-(void)goBack 
    [self.navigationController popViewControllerAnimated:YES];  

【讨论】:

【参考方案7】:

在viewDidLoad或loadView中添加如下代码

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

我在装有 iOS 9 的 iPhone 和 iPad 上对其进行了测试

【讨论】:

应该是 self.navigationController?.navigationBar.backItem?.title = "自定义文本" 我需要的唯一区别是navigationControllertopItem 属性上的可选链接,例如:self.navigationController?.navigationBar.topItem?.title = "Custom Text"【参考方案8】:

添加到缰绳的答案。从 Apple 的文档中注意到 backBarButtonItem 的声明是这样的:

@property(nonatomic, retain) UIBarButtonItem *backBarButtonItem

因此,rein 的答案会泄漏内存,因为合成的 setter 将 retain 你传递给它的实例,它永远不会显式释放。您可以使用autorelease 解决此问题

 self.navigationItem.backBarButtonItem = 
      [[[UIBarButtonItem alloc] initWithTitle:@"Custom Title" 
         style:UIBarButtonItemStyleBordered
         target:nil
         action:nil] autorelease];  //<-- autoreleased

或者您可以将一个变量指向实例,以便稍后显式释放它:

UIBarButtonItem* item = ...
self.navigationItem.backBarButtonItem = item;
[item release];

希望这会有所帮助!

【讨论】:

请注意,现在使用 ARC,您无需担心自动发布(如果您尝试在启用 ARC 的项目中自动发布,编译器确实会出错)【参考方案9】:
- (void)viewDidLoad 
  [super viewDidLoad];

  UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
  self.navigationItem.backBarButtonItem = backButton;
  [backButton release];

【讨论】:

【参考方案10】:

我发现了一些有趣的东西。 如果您继承 UINavigationController 并覆盖 pushViewController:animated: 方法并执行以下操作:(请记住,我使用的是 ARC)

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] 
 initWithTitle: @"Back" 
 style: UIBarButtonItemStyleBordered
 target: nil action: nil];

viewController.navigationItem.backBarButtonItem = backButton;

[super pushViewController:viewController animated:animated];

然后,对于使用导航控制器推送的所有ViewControllers,将自动在其中包含“返回”按钮。如果您想更改某些视图控制器的文本,您可以尝试将视图控制器转换为某个类或您自己的自定义协议(您的视图控制器继承自该协议可能具有像 backButtonText 这样的方法或类似的东西)哪个可以为您提供有关即将到来的视图控制器的某些信息,以便您可以为其自定义后退按钮文本。现在后退按钮文本在一个应该单独负责的地方处理。我不得不承认,创建一个新按钮来更改文本很糟糕,但是好吧。

谁能想到不这样做的理由?至少您不必摆弄视图控制器的标题,也不必记住在将视图控制器推到导航控制器上之前创建一个新的后退按钮。

【讨论】:

【参考方案11】:

rein 的回答效果很好。

请注意,如果您按下多个视图控制器,更改后的后退按钮标题将为它们中的每一个显示,这可能不是您想要的。

在这种情况下,您需要在每次推送视图控制器时创建自定义 UIBarButtonItem。

另外,请确保在推动视图控制器之前 执行此操作,否则您会在标题更改时出现屏幕卡顿。

【讨论】:

【参考方案12】:

根据 Aubrey 的建议,您可以在子视图控制器中执行此操作:

创建两个变量,用于存储父代的navigationItem.title和父代的navigationItem的旧值

UINavigationItem* oldItem;
NSString* oldTitle;

viewDidLoad 中,添加以下内容:

oldItem = self.navigationController.navigationBar.topItem;  
oldTitle = oldItem.title;  
[oldItem setTitle: @"Back"];  

viewWillDisappear 中,添加以下内容:

[oldItem setTitle: oldTitle];  
oldTitle = nil;  // do this if you have retained oldTitle
oldItem = nil;   // do this if you have retained oldItem

这并不完美。随着新控制器的动画化,您将看到父视图的标题发生变化。但这确实实现了自定义标记后退按钮并使其形状像标准后退按钮的目标。

【讨论】:

【参考方案13】:

把这个给你viewDidLoad,希望它会变成你要找的东西

UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" 
style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backBarButtonItem;
[backBarButtonItem release];

【讨论】:

【参考方案14】:

如果您想在 ARRIVING 控制器中设置标题(有时更符合逻辑..) 在 swift 3 中:

func setBackButtonNavBar(title: String, delay: Double)

    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute:  () -> Void in

        if let navBar = self.navigationController?.navigationBar
            navBar.backItem?.title = title
        
    )


在即将推出的控制器中:

override func viewDidLoad() 
    super.viewDidLoad()
    self.setBackButtonNavBar(title: "back", delay: 0.3)

通常我将 self.setBackButtonNavBar 放在控制器扩展中。

【讨论】:

【参考方案15】:

我知道这是一个老问题,答案已经更新了!

简单的方法是在父 ViewController 中执行此操作:

即带你到下一个视图控制器的那个。

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

【讨论】:

【参考方案16】:

在代码中执行此操作会删除 UINavigationConroller 的后退按钮样式。如果在每个视图中添加导航项,则可以在StoryBoard 中设置后退按钮的标题。

【讨论】:

以上是关于UINavigationController“后退按钮”自定义文本?的主要内容,如果未能解决你的问题,请参考以下文章

捕捉 UINavigationController 本机后退按钮操作

如何在 uinavigationcontroller 中隐藏后退按钮

UINavigationController后退按钮动作问题

无法在 UINavigationController 上设置后退按钮

UINavigationController 不显示后退按钮

UINavigationController 上的后退按钮