Как изменить заголовок кнопки "Назад" на панели навигации

В настоящее время значением по умолчанию для левой кнопки является заголовок представления, загружающего текущий, другими словами, представление, которое будет отображаться при нажатии кнопки (кнопка возврата).

Я хочу изменить текст, показанный на кнопке, на что-то еще.

Я попытался поместить следующую строку кода в метод viewDidLoad контроллера просмотра, но он не работает.

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

Что мне делать?

Спасибо.

Ответ 1

Это должно быть помещено в метод, который вызывает ViewController под названием "NewTitle". Прямо перед оператором push или popViewController.

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

Ответ 2

В ChildVC это сработало для меня...

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

Работает также в Swift!

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

Ответ 3

Вот документация для backBarButtonItem:

"Когда этот элемент навигации находится под верхним элементом в стек, контроллер навигации выводит кнопку" Назад "для панель навигации из этого пункта навигации. [...] Если ты хочешь указать пользовательское изображение или заголовок для кнопки" Назад ", вы можете назначить пользовательский элемент кнопки панели (с вашим пользовательским названием или изображением) к этому собственности".

View Controller 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 back имеет заголовок "Short".

Ответ 4

в Xcode 4.5 с помощью раскадровки, на самом деле самым простым решением, которое я нашел, когда значение кнопки "Назад" не нужно динамически менять, - это использовать поле "Назад" , связанное с элементом навигации контроллера просмотра на который вы хотите, чтобы кнопка "Назад" говорила что-то еще.

например. на скриншоте ниже, я хочу кнопку "Назад" для контроллера (ов) просмотра, который я нажимаю, чтобы иметь "Назад" в качестве названия кнопки "Назад" .

enter image description here

конечно, это не сработает, если вам понадобится кнопка "Назад" , чтобы сказать что-то немного другое каждый раз... для этого есть все другие решения.

Ответ 5

Я знаю, вопрос очень старый, но я нашел хорошее решение.

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

Работает с childView! Протестировано с iOS 7.

Ответ 6

Возможно, я слишком упрощен, но из документации Apple формулировка:

Если элемент управления пользовательский не указан ни одним из контроллеров представления, используется кнопка default back, и ее заголовок устанавливается на значение заголовка свойство предыдущего контроллера представления, то есть контроллер просмотра на один уровень вниз в стеке.

Решение, помеченное правильно, устанавливает элемент кнопки по умолчанию из родительского контроллера. Это правильный ответ, но я решаю проблему, изменяя свойство self.title UIViewController прямо перед тем, как нажать новый контроллер на стек NavigationController.

Это автоматически обновляет заголовок кнопки назад на следующем контроллере, и пока вы установите self.title на то, что должно быть в viewWillAppear, я не вижу этот метод, вызывающий слишком много проблем.

Ответ 7

В Swift/iOS8 для меня работало следующее:

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

self.navigationController.navigationBar.topItem.backBarButtonItem = backButton;

Отправлено из ответа Фелипе.

Ответ 8

Эта работа для меня лучше. Попробуйте:

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

Ответ 9

Хорошо, вот путь. Если у вас есть контроллер просмотра "первым", и вы переходите к другому контроллеру просмотра "второй", нажав кнопку или т.д., Вам нужно выполнить некоторую работу. Сначала вам нужно создать BarButtonItem в "втором" контроллере ViewDidLoad, например:

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

После этого вам нужно написать код для действия "btnBack" в том же файле .m, как это:

-(IBAction)OnClick_btnBack:(id)sender  {
      [self.navigationController popViewControllerAnimated:YES];
    //[self.navigationController pushViewController:self.navigationController.parentViewController animated:YES];
}

Что все.

Ответ 10

У меня был родительский контроллер представления с действительно длинным заголовком. Это привело к тому, что текст кнопки обратной кнопки истекал кровью в заголовок контроллера дочернего представления.

Попробовав кучу разных решений, это то, что я закончил (расширяя подход @john.k.doe):

Использование Xcode 7.2, Swift 2

  • В раскадровке добавьте Navigation Item в сцену диспетчера просмотра Родительский (не дочерний VC)

пункт навигации

  1. В Attributes Inspector вашего нового Navigation Item введите символ space в поле Back Button. Подробнее об этом позже.

элемент навигации в иерархии представлений

добавить символ пробела в поле Back Button

  1. В контроллере представления Родительский добавьте следующий код:

сниппет:

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

Для тех, кто использует раскадровки, просто выберите родительский (а не тот, который держит целевой вид), наблюдайте за рамкой контроллера (убедитесь, что вы нажимаете прямо на панели навигации, затем откройте инспектор атрибутов, в котором вы найдете три входных файла. третья "обратная кнопка" - это то, что мы ищем.

Ответ 12

Быстрая версия:

В вашем ребенке ViewController:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.backItem?.title = "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

ок. Я лично ненавидел все эти варианты. Поэтому я придумал свои собственные.

Основываясь на информации, которую я видел. Похоже, что контроллер предыдущего представления контролирует свою собственную кнопку "Назад", которая будет отображаться на толкаемом контроллере представления.

Я создал метод Lazy Load для элемента navigationItem на контроллере, который хочет изменить кнопку "Назад".

Mine - это контроллер покупателя приглашения

Приглашение Покупателя - это текст, который установлен по умолчанию.

но кнопка "Назад" должна быть приглашена.

Вот код, который я использовал для создания кнопки "Назад".

Я помещал этот код в верхнюю часть файла Controller Implementatio (.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;
}

Я чувствую, что это гораздо более элегантный способ добиться этого.

Я размещаю этот код в одном месте, и он автоматически заполняется по мере необходимости.

Не нужно вызывать код перед каждым запросом на push.

Надеюсь, что это поможет

Ответ 15

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

Ответ 16

Вот ответ:

В viewDidAppear:animated (НЕ в viewDidLoad) выполните следующие

- (void)viewDidAppear:(BOOL)animated
{
     [self.navigationController.navigationBar.backItem setTitle:@"anything"];

     // then call the super
     [super viewDidAppear:animated];
}

Это, если вы хотите сохранить форму кнопки "Назад".

Ответ 17

Ни одно из объясненных здесь решений не помогло мне. Так что я сделал это, удалил название со сцены, откуда я пришел, следующим образом:

self.title = @"";

Итак, когда представлена ​​новая сцена, задний текст не появляется.

Я абсолютно согласен с тем, что это не совсем ясное решение, но работало, и ни один из объясняемых не работал у меня.

Ответ 18

Для 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

Ответ 19

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

И в Свифте:

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

Ответ 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

Я обнаружил, что лучше всего изменить заголовок текущего контроллера представления в стеке навигации до нужного текста кнопки "Назад", прежде чем перейти к следующему контроллеру представления.

Например

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

Затем в viewDidAppear верните заголовок на нужный заголовок для исходного VC. Вуаля!

Ответ 23

Im new в 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

Ответ 24

self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] 
                                              initWithTitle:@"Log out" 
                                              style:UIBarButtonItemStyleDone 
                                              target:nil 
                                              action:nil] autorelease];

вы можете поместить его в любом коде в партер-контроллере, что позволит вам иметь разные подножки для разных дочерних видов.

Ответ 25

Большинство решений уничтожает оригинальный стиль BackButton (кнопка со стрелкой влево) при добавлении обычной кнопки с нужным названием.
Итак, чтобы сохранить оригинальный стиль, есть 2 способа:
1-й: использовать недокументированный стиль кнопки (110 или что-то в этом роде), который я предпочитаю не делать. Но если вы хотите, вы можете найти, как это сделать здесь, в stackoverflow.
2: Использовать идею Тренцова. Мне понравилось, и я использую его немного измененный.
Вместо того, чтобы переопределять - (NSString *) заголовок, я решил сохранить исходный заголовок следующим образом (что позволяет мне использовать названия nib, а также заданный заголовок в состоянии состояния BT).

- (void)viewDidLoad {
    [super viewDidLoad];
    static NSString * [email protected]"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 раза.
Также я пробовал решение Jessc, но он выглядит плохо. Это приводит к появлению видимых изменений заголовка заголовка пользователя на лету от оригинала до требуемого и обратно BackButton.

Ответ 26

Это работает для меня как "упрощенная" версия предыдущих опубликованных ответов.

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] init];

backButton.title = @"Go Back";

self.navigationItem.backBarButtonItem = backButton;

Не забудьте поставить код внутри родительского контроллера представления (например, представление, которое имеет представление в виде таблицы или UITableViewController), не дочернее или детальное представление (например, UIViewController).

Вы можете легко локализовать строку кнопки назад следующим образом:

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

Ответ 27

У нас есть два 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)

Ответ 28

Ответ Стэна был лучшим. Но это также имеет проблему, когда вы используете контроллер с панелью вкладок и меняете заголовок контроллера, вы также можете изменить заголовок панели вкладок. Так что лучшим ответом является изменение только view_controller.navigationItem.title и использование view_controller.navigationItem.title в функции. Ответ здесь: (С ARC и добавьте их в viewDidLoad)

  static NSString * [email protected]"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 * [email protected]"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;
  }
}

Ответ 29

Если вы хотите не только изменить текст кнопки "Назад" на тот же текст и оставаться исходной фигурой в левой стрелке, но и делать что-то, когда пользователь нажимает кнопку "Назад", я рекомендую вам осмотреть мой " CustomNavigationController".

Ответ 30

Согласно документу UINavigationBar > backItem

enter image description here

Если свойство leftBarButtonItem самого верхнего элемента навигации равно nil, на панели навигации отображается кнопка "Назад", название которой получено из элемента в этом свойстве.

Но установка backItem.backBarButtonItem не работает в первый раз viewWillAppear. Установка topItem.backBarButtonItem работает только в первый раз viewWillAppear. Потому что navigationBar.topItem все еще указывает на previousViewController.navigationItem. В viewWillLayoutSubviews topItem и backItem обновляются. Поэтому после первого просмотра viewWillAppear мы должны установить backItem.backBarButtonItem.

ОТВЕТ: Установка backBarButtonItem для navigationItem элемента предыдущего viewController независимо от того, когда и где в вашем текущем viewController (верхний viewController). Вы можете использовать этот код в viewWillAppear или viewDidLoad. Посмотрите мой пост в блоге iOS Установите заголовок кнопки "Назад" для подробного анализа.

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