首页 文章

如何更改导航栏上“后退”按钮的 Headers

提问于
浏览
218

目前,左栏按钮默认值是加载当前视图的视图的 Headers ,换句话说,按下按钮时显示的视图(后退按钮) .

我想将按钮上显示的文本更改为其他内容 .

我尝试在视图控制器的viewDidLoad方法中放入以下代码行,但它似乎不起作用 .

self.navigationItem.leftBarButtonItem.title = @"Log Out";

我该怎么办?

谢谢 .

30 回答

  • 17

    如果您不仅希望将“后退”按钮的文本更改为相同的文本并保持原始的左箭头形状,而且还要在用户单击“后退”按钮时执行某些操作,我建议您查看我的“CustomNavigationController” .

  • 56

    问题:导航栏中的“后退”文本无法替换 .

    原因:推送视图后,导航栏中设置了“返回”标签,因为父视图控制器中的.title属性设置为nil(或未初始化) .

    一个解决方案:如果您设置self.title =“Whatever ...”,您将看到在推动新视图控制器后,而不是“Back”将显示“Whatever ...” .

  • 41

    这应该放在调用 Headers 为“NewTitle”的ViewController的方法中 . 就在push或popViewController语句之前 .

    UIBarButtonItem *newBackButton = 
            [[UIBarButtonItem alloc] initWithTitle:@"NewTitle" 
                                             style:UIBarButtonItemStyleBordered 
                                            target:nil 
                                            action:nil];
    [[self navigationItem] setBackBarButtonItem:newBackButton];
    [newBackButton release];
    
  • 5

    在ChildVC中,这对我有用......

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

    也适用于Swift!

    self.navigationController!.navigationBar.topItem!.title = "Back"
    
  • 91

    以下是 backBarButtonItem 的文档:

    “当此导航项位于堆栈顶部项目的正下方时,导航控制器将从此导航项目中导出导航栏的后退按钮 . [...]如果要为后面指定自定义图像或 Headers 按钮,您可以将自定义栏按钮项目(包含您的自定义 Headers 或图像)分配给此属性 . “

    查看控制器A( "parent" 视图控制器):

    self.title = @"Really Long Title";
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Short" style:UIBarButtonItemStyleBordered target:nil action:nil];
    self.navigationItem.backBarButtonItem = backButton;
    

    当任何其他视图控制器B位于导航堆栈的顶部,并且A位于其下方时,B的后退按钮将具有 Headers "Short" .

  • 1

    在Xcode 4.5中使用storyboard,到目前为止,当Back按钮的值不必动态更改时,我发现最简单的解决方案是使用与View Controller的导航项相关联的“Back Button”字段想要“后退”按钮说出别的话 .

    例如在下面的屏幕截图中,我想要视图控制器的后退按钮,我推动将“后退”作为后退按钮的 Headers .

    enter image description here

    当然,如果你需要后退按钮每次都说一些略微不同的东西,这将不起作用......这里有所有其他解决方案 .

  • 3

    我知道,问题很老,但我找到了一个很好的解决方案 .

    UIBarButtonItem *barButton = [[UIBarButtonItem alloc] init];
    barButton.title = @"Custom Title";
    self.navigationController.navigationBar.topItem.backBarButtonItem = barButton;
    

    从childView工作!经过iOS 7测试 .

  • 25

    也许我过于简单,但从Apple的文档中可以看出:

    如果任一视图控制器未指定自定义栏按钮项,则使用默认后退按钮,并将其 Headers 设置为上一个视图控制器的title属性的值,即视图控制器向下一级在堆栈上 .

    上面标记为正确的解决方案从父控制器设置默认按钮项 . 它通过在将新控制器推送到NavigationController堆栈之前更改UIViewController的 self.title 属性来解决问题 .

    这会自动更新下一个控制器上的后退按钮的 Headers ,只要你将 self.title 设置回 viewWillAppear 中的内容,我就看不到这种方法造成太多问题了 .

  • 2

    这项工作对我来说更好 . 试试:

    self.navigationController.navigationBar.topItem.backBarButtonItem = [[UIBarButtonItem alloc] 
    initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
    
  • 1

    在Swift / iOS8中,以下内容对我有用:

    let backButton = UIBarButtonItem(
          title: "Back Button Text",
          style: UIBarButtonItemStyle.Bordered,
          target: nil,
          action: nil
    );
    
    self.navigationController.navigationBar.topItem.backBarButtonItem = backButton;
    

    来自费利佩的回答 .

  • 6

    好的,这是方法 . 如果你有一个视图控制器“第一”,你通过按下按钮等导航另一个视图控制器“秒”,你需要做一些工作 . 首先,您需要在“第二”视图控制器的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];
    }
    

    就这样 .

  • 3

    使用下面的代码行:

    UIBarButtonItem *newBackButton =
    [[UIBarButtonItem alloc] initWithTitle:@"hello"
                                     style:UIBarButtonItemStylePlain
                                    target:nil
                                    action:nil];
    
    self.navigationItem.leftBarButtonItems =[[NSArray alloc] initWithObjects:newBackButton, nil];
    
    self.navigationItem.leftItemsSupplementBackButton = YES;
    
  • 4

    我有一个父视图控制器, Headers 很长 . 这导致后退按钮文本渗透到子视图控制器的 Headers 中 .

    在尝试了一堆不同的解决方案之后,这就是我最终做的事情(扩展@ john.k.doe方法):

    使用Xcode 7.2,Swift 2

    • 在故事板中,将 Navigation Item 添加到 Parent View Controller场景(不是子VC)

    navigation item

    • 在新 Navigation ItemAttributes Inspector 上,在 Back Button 字段中键入 space 字符 . 稍后会详细介绍 .

    navigation item in View Hierarchy

    add a space character to the Back Button field

    • Parent 视图控制器中,添加以下代码:

    片段:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        switch segue.destinationViewController {
        case is ChildViewController:
            navigationItem.backBarButtonItem?.title = ""
        default:
            navigationItem.backBarButtonItem?.title = "Full Parent Title"
        }
    }
    

    Explanation:

    后退按钮排序属于父视图控制器 . Navigation Item 为您提供了后退按钮的句柄,因此您可以在代码或故事板中设置 Headers .

    Note:

    如果将 Navigation Item Back Button 文本保留为默认空字符串,则后退按钮 Headers 将变为"Back" .

    Other approaches work, why use this one?:

    虽然可以覆盖子视图控制器上的后退按钮 Headers ,但是在它已经在屏幕上短暂闪烁之前获取它是一个挑战 .

    一些方法构造一个新的后退按钮并覆盖现有的后退按钮 . 我确信它有效,在某些用例中可能是必要的 . 但我更愿意尽可能利用现有的API .

    在某些情况下,更改父视图控制器的 title 是最快的解决方案 . 但是,这会更改父 Headers ,因此您必须管理状态 . 事情也变得混乱 Tab Bar Controller 因为 Headers 更改会导致 Tab Bar Item Headers 出现副作用 .

  • 15

    对于那些使用故事板的人,只需选择父级(不是持有目标视图的那个)视图控制器框架(确保在导航栏上单击右键,然后打开属性检查器,您将在其中找到三个表单输入 . 第三个“后退按钮“是我们正在寻找的 .

  • 7

    Swift版本:

    在您的孩子ViewController中:

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.navigationBar.backItem?.title = "TEXT"
    }
    
  • 18

    这是另一种方法 .

    在父视图控制器中,实现以下方法:

    - (void) setBackBarButtonItemTitle:(NSString *)newTitle {
      self.navigationItem.backBarButtonItem.title = newTitle;
    }
    

    在子视图控制器中,当您想要更改 Headers 时,这将起作用:

    NSArray *viewControllerArray = [self.navigationController viewControllers];
    int parentViewControllerIndex = [viewControllerArray count] - 2;
    [[viewControllerArray objectAtIndex:parentViewControllerIndex] setBackBarButtonItemTitle:@"New Title"];
    

    我无法让 parentViewController 属性工作:

    [(ParentViewController *)(self.navigationController.parentViewController) setBackBarButtonItemTitle:@"New Title"];
    

    我没有't know if that'是一个错误,或者我没有正确使用它 . 但 grab viewControllers 数组中倒数第二个视图控制器指向父视图控制器,我可以使用该引用正确调用父方法 .

  • 5

    好 . 我个人讨厌所有这些选择 . 所以我想出了自己的 .

    根据我看到的信息 . 看起来,前一个视图控制器控制着自己的“后退”按钮,该按钮将在推动的视图控制器上显示 .

    我为需要更改后退按钮的控制器上的navigationItem创建了一个Lazy Load方法 .

    我是一名邀请买家控制员

    Invite Buyer是默认设置的文本 .

    但后退按钮必须是邀请

    这是我用来创建后退按钮的代码 .

    我将此代码放在Controller的Implementatio(.m)文件的顶部,它自动覆盖了super的方法 .

    - (UINavigationItem *)navigationItem{
        UINavigationItem *item = [super navigationItem];
        if (item != nil && item.backBarButtonItem == nil)
        {
            item.backBarButtonItem = [[[UIBarButtonItem alloc] init] autorelease];
            item.backBarButtonItem.title = @"Invite";
        }
    
        return item;
    }
    

    我觉得这是一种更优雅的方式来实现这一目标 .

    我将此代码放在一个位置,并在需要时自动填充 .

    无需在每个推送请求之前调用代码 .

    希望这可以帮助

  • 1
    UIBarButtonItem *btnBack = [[UIBarButtonItem alloc]
                                       initWithTitle:@"Back" 
                                       style:UIBarButtonItemStyleBordered
                                       target:self
                                       action:@selector(OnClick_btnBack:)];
        self.navigationItem.leftBarButtonItem = btnBack;
        [btnBack release];
    
  • 4

    这是答案:

    viewDidAppear:animated (不在 viewDidLoad 中)执行以下操作

    - (void)viewDidAppear:(BOOL)animated
    {
         [self.navigationController.navigationBar.backItem setTitle:@"anything"];
    
         // then call the super
         [super viewDidAppear:animated];
    }
    

    如果你想保持后退按钮的形状 .

  • 4

    这里解释的解决方案都不适用于我 . 所以我做的是从我来自的场景中删除 Headers ,方法如下:

    self.title = @"";

    因此,当呈现新场景时,不显示背面文本 .

    我绝对同意这根本不是一个明确的解决方案,但是有效,并且没有一个解释为我工作 .

  • 4

    对于Swift:

    // 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
    
  • 4

    我发现,更改后退按钮名称的最简单方法是将视图控制器 Headers 设置为后退按钮的 Headers ,然后将视图控制器导航项中的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中的 Headers 看起来好像是原生的 . 赋予视图控制器分离 Headers 和后退按钮 Headers 的能力 .

    在视图控制器A和B的情况下,A负责告知它的后退按钮应该如何显示,同时显示B.

    编辑:这也保持后退按钮本机外观(左箭头栏按钮项) .

  • 1

    这段代码也有效 . 把它放在导航控制器的根控制器上:

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

    我发现在推送到下一个视图控制器之前,最好将导航堆栈中当前视图控制器的 Headers 更改为后退按钮的所需文本 .

    例如

    self.navigationItem.title = @"Desired back button text";
    [self.navigationController pushViewController:QAVC animated:NO];
    

    然后在viewDidAppear中将 Headers 设置回原始VC的所需 Headers . 瞧!

  • 338

    我是iOS的新手,但我将提供覆盖导航控制器类的非常简单的答案 . 我有简单的覆盖push和pop方法并保存以前的视图控制器的 Headers . 很抱歉在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
    
  • 9

    self.navigationController.navigationBar.backItem.title = @"TEXT";

    在斯威夫特:

    self.navigationController?.navigationBar.backItem?.title = "TEXT"
    
  • 5
    self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] 
                                                  initWithTitle:@"Log out" 
                                                  style:UIBarButtonItemStyleDone 
                                                  target:nil 
                                                  action:nil] autorelease];
    

    您可以在parrent控制器的代码中将它放在您喜欢的位置,这样您就可以为不同的子视图设置不同的背景按钮 .

  • 78

    大多数解决方案都会杀死BackButton的原始样式(左箭头栏按钮),同时添加一个具有所需 Headers 的常用按钮 .
    所以保持原始风格有两种方式:
    1st:使用我不想做的无证按钮样式(110或类似的东西) . 但是,如果你想要,你可以在stackoverflow上找到如何做到这一点 .
    第二:使用我的Trenskow的想法 . 我喜欢它,我使用它有点改变 .
    而不是覆盖 - (NSString *) Headers 我've decided to keep the original title in the following way (which allows me to use nib'的 Headers 以及推送状态btw的给定 Headers .

    - (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次 .
    我也是解决方案,但看起来很糟糕 . 它会导致用户 Headers 栏的可见性从原始状态变为BackButton的所需和返回 .

  • 5

    这对我来说是以前发布的答案的“简化”版本 .

    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] init];
    
    backButton.title = @"Go Back";
    
    self.navigationItem.backBarButtonItem = backButton;
    

    请记住将代码放在父视图中控制器(例如具有您的表视图或UITableViewController的视图), not 子视图或详细视图(例如UIViewController) .

    您可以轻松地本地化后退按钮字符串,如下所示:

    backButton.title = NSLocalizedString(@"Back Title", nil);
    
  • 18

    斯坦的回答是最好的 . 但它也有一个问题,当你使用带有标签栏的控制器并更改控制器的 Headers 时,你也可以更改标签栏的 Headers . 所以最好的答案是只更改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;
      }
    }
    

相关问题