UINavigationController «кнопка возврата» пользовательский текст?


147

Кнопка «Назад» UINavigationControllerпо умолчанию показывает заголовок последнего представления в стеке. Есть ли способ иметь собственный текст вместо кнопки «Назад»?


1
Эта работа для меняself.navigationController.navigationBar.topItem.title = @"Custom text";
Huync

Ответы:


342

По этой ссылке :

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

Как сказал Тайлер в комментариях:

не делайте этого в видимом контроллере вида, но в контроллере вида, который вы увидите, если нажмете кнопку возврата


4
Вы должны . releaseUIBarButtonItem
Мехрдад Афшари

217
Также обратите внимание, что вам нужно сделать это в контроллере представления на один уровень вверх по стеку. Другими словами, не делайте этого в видимом контроллере представления, но в контроллере представления, который вы увидите, если нажмете кнопку возврата.
Тайлер

6
Просто, чтобы прояснить комментарий Тайлера, потому что я сначала не понял этого: установка backBarButtonItem в контроллерах представления navigationItem устанавливает кнопку, которая будет отображаться, чтобы получить BACK для этого контроллера представления. Также обратите внимание, что, хотя у кнопки со стрелкой нет стиля, эта кнопка все равно получит стиль стрелки. Я использовал UIBarButtonItemStylePlain и все еще получаю стиль кнопки со стрелкой.
Джон Штайнметц

3
Предложение: Вместо того, чтобы предполагать стиль, передайте текущий установленный стиль. В этом коде ответа замените UIBarButtonItemStyleBorderedна звонок в собственность self.navigationItem.backBarButtonItem.style. Документация: developer.apple.com/library/ios/documentation/uikit/reference/…
Василий Бурк

1
Обратите внимание, что в соответствии с ARC вы должны пропустить авто-релиз вызова. поэтому у вас есть self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: @ Стиль «Пользовательское название»: UIBarButtonItemStyleBordered target: nil action: nil];
bkbeachlabs

43

Вы можете установить текст в Интерфейсном Разработчике:

Выберите элемент навигации ViewController, к которому вернется кнопка «Назад»:

введите описание изображения здесь

В инспекторе атрибутов панели утилит введите свой ярлык для кнопки «Назад»:

введите описание изображения здесь

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

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


Это лучший ответ, который я нашел до сих пор.
Аян Сенгупта

2
Чтобы было ясно, это должно быть установлено в элементе навигации контроллера представления, а не в самом инспекторе атрибутов контроллера представления.
Патрик

Это лучший ответ, который я нашел.
bicepjai

Это лучший ответ
Алекс Браун

2
Начиная с Xcode 6.1.1 и работающего в iOS 7, кажется, что ваш первоначальный заголовок предыдущего представления все равно переопределит любой заголовок кнопки возврата, который вы здесь установили. Если заголовок предыдущего представления содержит более 11 символов, тогда кнопка «Назад» следующего просмотра просто скажет «Назад». Там нет никакого способа, кроме как создать новый элемент панели навигации с нуля, как показано в ответе с самым высоким рейтингом здесь.
луч

22

Я использую это:

// 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";
}

Это почти работает для меня, но когда я нажимаю кнопку «Назад», текст меняется на название родителя на время анимации :-(
Дэнни Таппени

3
Это изменяет заголовок кнопки «Назад» контроллера в стеке. Это не меняет заголовок кнопки «Назад» текущего отображаемого контроллера. Еще хуже: он меняет название контроллера, предшествующее предыдущему контроллеру!
Левиафан

Как отмечали другие комментаторы, этот метод немного несостоятельный. Я бы не советовал делать это, потому что API на самом деле не предназначен для его использования. Вы могли бы настраивать себя на сложные ошибки в будущем!
RickDT

11

Я нашел удобное решение для этого, просто установив заголовок контроллера перед тем, как поместить другой контроллер в стек, например:

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

Затем убедитесь, что оригинальное название установлено viewWillAppearтак:

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

Это работает, потому что по умолчанию UINavigationControllerпри создании кнопки «Назад» во время операции нажатия используется заголовок предыдущего контроллера.


1
Проблема в том, что заголовок меняется на старом виде, так как он оживляет и выглядит немного невнятным. Кажется, что ни одно из приведенных здесь решений не работает так, как вам хотелось бы :-(
Дэнни Таппени,

1
Это идеально в моей ситуации, потому что я не показываю NavBar на предыдущем экране, и я просто хочу удалить titleLabel с кнопки «Назад» на новом экране и иметь только шевронную стрелку iOS7. Поэтому я могу просто установить пустой литерал NSString для заголовка.
Сибур

Нажатие контроллера представления поднимает исключение при нажатии на спину
Sumit

7

Название кнопки «Назад» по умолчанию соответствует заголовку предыдущего представления, поэтому я использую быстрый прием, чтобы поместить следующий код в файл .m предыдущего представления.

-(void)viewWillAppear:(BOOL)animated {

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

-(void)viewWillDisappear:(BOOL)animated {

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

Это работает довольно хорошо во многих случаях, и это довольно просто ... только наблюдение состоит в том, что переопределение любого из этих методов требует, чтобы реализация super была вызвана в какой-то момент в новом методе.
Izk

2
С помощью этого метода можно заметить, что заголовок родительского представления изменяется на «Назад», прежде чем произойдет анимация push. (И, похоже, отстой, если вы переместите это в метод viewDidDisappear, вы увидите, что переключение происходит после нажатия ...)
Джеймс Бутчер

Мне нравится этот метод, но проблема, с которой я сталкиваюсь, заключается в том, что «Оригинальный заголовок» устанавливается нормально, но с многоточием, если он длиннее «Назад», что должно быть потому, что представление еще не находится в иерархии представлений. , он не передает вид заголовка. Проблема, описанная @JamesBoutcher выше, для меня незаметна из-за высокой начальной скорости анимации. На самом деле, я только что понял, что проблема, с которой я сталкиваюсь, особенно заметна из-за медленной анимации, когда эта проблема заметна.
trss

Несмотря на то, что ответ на stackoverflow.com/questions/1441699/… кажется больше настройки, чем необходимо, это документированный способ и, что более важно, кажется более согласованным с нашими намерениями.
trss

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

3

Добавьте следующий код в viewDidLoad или loadView

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

Я проверил это в iPhone и iPad с iOS 9


Должен быть self.navigationController? .NavigationBar.backItem? .Title = "Пользовательский текст"
Peacemoon

1
Единственное различие я нужен был дополнительный сцепление на navigationControllerи topItemсвойств, например:self.navigationController?.navigationBar.topItem?.title = "Custom Text"
Bulwinkel

2

Добавление к ответу повести. Обратите внимание на документы Apple, что объявление backBarButtonItem таково:

@property(nonatomic, retain) UIBarButtonItem *backBarButtonItem

Поэтому ответ Rein утечет память, потому что синтезированный сеттер будет 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)
Эрик Голдберг

2
- (void)viewDidLoad {
  [super viewDidLoad];

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

2

Я обнаружил что-то интересное. Если вы наследуете метод 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что нажимается вашим навигационным контроллером, будет автоматически нажата кнопка «Назад». Если вы хотите изменить текст для определенных контроллеров представления, вы можете попробовать и, возможно, привести viewcontroller к определенному классу или вашему собственному пользовательскому протоколу (который наследует ваш viewcontroller, от которого может быть подобный метод backButtonTextили что-то глупое), который может дать вам определенная информация о контроллере представления, которая поступает так, что вы можете настроить для нее текст кнопки «назад». Теперь текст кнопки «Назад» обрабатывается в месте, которое должно нести ответственность. Я должен признать, что создание новой кнопки для изменения текста отстой, ну да ладно.

Может кто-нибудь придумать причину, почему бы не сделать это так? По крайней мере, вам не нужно возиться с названиями viewcontroller или не забывать создавать новую кнопку назад, прежде чем нажимать viewcontroller на контроллере навигации.


0

Ответ Рейна работает хорошо.

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

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

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


0

Разобравшись с предложением Обри, вы можете сделать это в контроллере дочернего представления:

создать две переменные для хранения старых значений родительского файла navigationItem.title и родительского элемента навигации

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

Это не идеально. Вы увидите, как изменяется название родительского представления, когда новый контроллер анимирован. НО это действительно позволяет создать специальную метку для кнопки «Назад» и сохранить ее форму в виде стандартной кнопки «Назад».


0

Поместите это в себя viewDidLoad, надеюсь, это приведет к тому, что вы ищете

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

0

если вы хотите установить заголовок в контроллере 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 в расширение контроллера.


0

Я знаю, что это старый вопрос, и ответы вроде как обновлены!

Самый простой способ сделать это в родительском ViewController:

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

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

-1

Делая это в коде, удалите стиль кнопки «Назад» UINavigationConroller. Если вы добавляете элемент навигации в каждое из ваших представлений, вы можете установить заголовок задней кнопки в StoryBoard.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.