Как мне изменить название кнопки “Назад” на панели навигации
-
11-09-2019 - |
Вопрос
В настоящее время значением по умолчанию для кнопки левой панели является заголовок представления, которое загрузило текущее, другими словами, представление, которое будет отображаться при нажатии кнопки (кнопка назад).
Я хочу изменить текст, отображаемый на кнопке, на что-то другое.
Я попытался поместить следующую строку кода в метод viewDidLoad контроллера представления, но, похоже, это не работает.
self.navigationItem.leftBarButtonItem.title = @"Log Out";
Что мне следует делать?
Спасибо.
Решение
Это должно быть помещено в метод, который вызывает ViewController под названием "newTitle".Непосредственно перед операцией push или popViewController.
UIBarButtonItem *newBackButton =
[[UIBarButtonItem alloc] initWithTitle:@"NewTitle"
style:UIBarButtonItemStyleBordered
target:nil
action:nil];
[[self navigationItem] setBackBarButtonItem:newBackButton];
[newBackButton release];
Другие советы
В childVC это сработало для меня...
self.navigationController.navigationBar.topItem.title = @"Back";
Работает и в Swift!
self.navigationController!.navigationBar.topItem!.title = "Back"
Вот документация для 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кнопка " Назад " будет иметь заголовок "Короткий".
в Xcode 4.5 с использованием раскадровки, безусловно, самое простое решение, которое я нашел, когда значение кнопки "Назад" не должно изменяться динамически, - это использовать поле "Кнопка назад", связанное с элементом навигации контроллера представления, к которому вы хотите, чтобы кнопка "Назад" указывала что-то еще.
например ,на скриншоте ниже я хочу, чтобы кнопка "Назад" для контроллеров просмотра, которую я нажимаю, имела "Назад" в качестве названия кнопки "Назад".
конечно, это не сработает, если вам нужно, чтобы кнопка "Назад" каждый раз говорила что-то немного другое ... для этого здесь есть все другие решения.
Я знаю, вопрос очень старый, но я нашел хорошее решение.
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] init];
barButton.title = @"Custom Title";
self.navigationController.navigationBar.topItem.backBarButtonItem = barButton;
Работает из childView!Протестировано с iOS 7.
Возможно, я излишне упрощаю, но из документации Apple следует формулировка:
Если a обычай элемент кнопки панели не указан ни одним из контроллеров представления, a кнопка возврата по умолчанию используется, и его заголовку присваивается значение свойства title предыдущего контроллера представления, то есть контроллера представления на один уровень ниже в стеке.
Решение, отмеченное как правильное выше, устанавливает элемент кнопки по умолчанию из родительского контроллера.Это правильный ответ, но я решаю проблему, изменяя self.title
свойство UIViewController непосредственно перед тем, как поместить новый контроллер в стек NavigationController.
Это автоматически обновит заголовок кнопки "Назад" на следующем контроллере, и до тех пор, пока вы устанавливаете self.title
вернуться к тому, в чем это должно быть viewWillAppear
Я не вижу, чтобы этот метод вызывал слишком много проблем.
Для меня это работает лучше.Попробуй :
self.navigationController.navigationBar.topItem.backBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
В Swift / iOS8 у меня сработало следующее:
let backButton = UIBarButtonItem(
title: "Back Button Text",
style: UIBarButtonItemStyle.Bordered,
target: nil,
action: nil
);
self.navigationController.navigationBar.topItem.backBarButtonItem = backButton;
Перенесено из ответа Фелипе.
Хорошо, вот способ.Если у вас есть контроллер просмотра "first" и вы перемещаетесь по другому контроллеру просмотра "second" нажатием кнопки или т.д.тебе нужно проделать кое-какую работу.Сначала вам нужно создать 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];
}
Вот и все.
У меня был родительский контроллер представления с очень длинным названием.Это привело к тому, что текст кнопки "Назад" перетек в заголовок дочернего контроллера представления.
Перепробовав кучу разных решений, вот что я в итоге сделал (развивая подход @john.k.doe):
Используя Xcode 7.2, Swift 2
- В раскадровке добавьте
Navigation Item
к тому Родитель Просмотр сцены контроллера (не дочернего VC)
- На
Attributes Inspector
о вашем новомNavigation Item
, введите вspace
персонаж вBack Button
поле.Подробнее об этом позже.
- В Родитель просмотр контроллера, добавьте следующий код:
фрагмент текста:
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
введите текст в качестве пустой строки по умолчанию, заголовок кнопки "Назад" станет "Back".
Другие подходы работают, зачем использовать этот?:
Хотя заголовок кнопки "Назад" на дочернем контроллере просмотра можно переопределить, было непросто разобраться с ним, пока он не успел ненадолго высветиться на экране.
Некоторые из подходов создают новую кнопку "Назад" и переопределяют существующую.Я уверен, что это работает и, вероятно, необходимо в некоторых случаях использования.Но я предпочитаю использовать существующие API, когда это возможно.
Изменение title
использование родительского контроллера представления является самым быстрым решением для некоторых ситуаций.Однако это изменяет родительский заголовок, поэтому вам придется управлять состоянием.Вещи также становятся беспорядочными с Tab Bar Controller
поскольку изменения названия вызывают побочные эффекты при Tab Bar Item
титулы.
Для тех, кто использует раскадровки, просто выберите родительский (не тот, который содержит целевой вид) фрейм контроллера представления (обязательно щелкните правой кнопкой мыши на панели навигации, затем откройте инспектор атрибутов, где вы найдете три формы ввода.Третья "кнопка назад" - это то, что мы ищем.
Быстрая версия:
В вашем дочернем ViewController:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.backItem?.title = "TEXT"
}
Вот еще один способ сделать это.
В вашем родительском контроллере представления реализуйте следующий метод:
- (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
массив указывает на родительский контроллер представления, и я могу корректно вызывать родительские методы по этой ссылке.
ОК.Лично я ненавидел все эти варианты.Поэтому я придумал свой собственный.
Основываясь на информации, которую я видел.Похоже, что Предыдущий контроллер просмотра управляет своей собственной кнопкой "Назад", которая будет представлена на нажатом контроллере просмотра.
Я создал метод отложенной загрузки для navigationItem на контроллере, который хочет изменить кнопку "Назад".
Мой - это Контроллер Приглашенного покупателя
Пригласить покупателя - это текст, который задан по умолчанию.
но кнопка "Назад" должна была быть Приглашающей
Вот код, который я использовал для создания кнопки "Назад".
Я поместил этот код в начало файла реализации контроллера (.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;
}
Я чувствую, что это гораздо более элегантный способ добиться этого.
Я помещаю этот код в одно место, и он автоматически заполняется при необходимости.
Нет необходимости вызывать код перед каждым push-запросом.
Надеюсь, это поможет
UIBarButtonItem *btnBack = [[UIBarButtonItem alloc]
initWithTitle:@"Back"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(OnClick_btnBack:)];
self.navigationItem.leftBarButtonItem = btnBack;
[btnBack release];
Вот вам и ответ:
В viewDidAppear:animated
(НЕ в viewDidLoad
) выполните следующие действия
- (void)viewDidAppear:(BOOL)animated
{
[self.navigationController.navigationBar.backItem setTitle:@"anything"];
// then call the super
[super viewDidAppear:animated];
}
Это если вы хотите сохранить форму кнопки "Назад".
Ни одно из описанных здесь решений не сработало для меня.Итак, что я сделал, так это удалил название из сцены, откуда я пришел, следующим образом:
self.title = @"";
Таким образом, при представлении новой сцены обратный текст не появляется.
Я абсолютно согласен, что это вообще не совсем ясное решение, но сработало, и ни одно из объясненных решений не сработало для меня.
Для 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
Я обнаружил, что самый простой способ изменить название кнопки "Назад" - это присвоить заголовку view controllers значение заголовка кнопки "Назад", а затем заменить titleView в элементе навигации view controllers на пользовательскую метку с ее реальным именем.
Вот так:
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 отображается.
Редактировать:При этом также сохраняется родной вид кнопки "Назад" (элемент кнопки на панели со стрелкой слева).
Этот код тоже работает.Поместите это на корневой контроллер навигационного контроллера:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
Я обнаружил, что лучше всего изменить заголовок текущего контроллера вида в стеке навигации на нужный текст кнопки "Назад", прежде чем переходить к следующему контроллеру вида.
Например
self.navigationItem.title = @"Desired back button text";
[self.navigationController pushViewController:QAVC animated:NO];
Затем в viewDidAppear верните заголовку желаемый заголовок для исходного VC.Вуаля!
Я новичок в 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
self.navigationController.navigationBar.backItem.title = @"TEXT";
И в Swift:
self.navigationController?.navigationBar.backItem?.title = "TEXT"
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc]
initWithTitle:@"Log out"
style:UIBarButtonItemStyleDone
target:nil
action:nil] autorelease];
вы можете поместить его куда угодно в коде parrent controller, что позволяет вам иметь разные обратные кнопки для разных дочерних представлений.
Большинство решений убивает оригинальный стиль BackButton (кнопка со стрелкой слева), добавляя обычную кнопку с желаемым заголовком.
Итак, чтобы сохранить оригинальный стиль, есть 2 способа:
1 - й:Использовать недокументированный стиль кнопки (110 или что-то в этом роде), чего я предпочитаю не делать.Но если вы хотите, вы могли бы найти, как это сделать, здесь, в stackoverflow.
2 - й:Чтобы использовать идею Тренскова.Мне это понравилось, и я использую его немного измененным.
Вместо переопределения заголовка - (NSString *) я решил сохранить исходный заголовок следующим образом (что позволяет мне использовать заголовки nib, а также заданный заголовок в состоянии push, кстати).
- (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 и обратно.
Это работает для меня как "упрощенная" версия предыдущих опубликованных ответов.
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] init];
backButton.title = @"Go Back";
self.navigationItem.backBarButtonItem = backButton;
Не забудьте поместить код внутрь родительского контроллера представления (напримерпредставление, в котором есть ваше табличное представление или UITableViewController), не дочерний или подробный вид (например,UIViewController).
Вы можете легко локализовать строку кнопки "Назад" следующим образом:
backButton.title = NSLocalizedString(@"Back Title", nil);
У нас есть два 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)
Ответ Стэна был самым лучшим.Но у этого также есть проблема, когда вы используете контроллер с панелью вкладок и меняете заголовок контроллера, вы также можете изменить заголовок панели вкладок.Таким образом, лучший ответ - изменить только view_controller.navigationItem.title и использовать view_controller.navigationItem.title в функции.Ответ здесь: (С помощью ARC и добавьте их в viewDidLoad 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;
}
}
Если вы хотите не только изменить текст кнопки "Назад" на тот же текст и сохранить исходную форму стрелки влево, но и что-то делать, когда пользователь нажимает кнопку "Назад", я рекомендую вам ознакомиться с моим "Пользовательский навигационный контроллер".
ПРОБЛЕМА:Текст "Назад" на панели навигации заменить нельзя.
Причина:Метка "Назад" устанавливается на панели навигации после нажатия на вид, потому что атрибуту .title в контроллере родительского вида было присвоено значение nil (или не инициализировано).
ОДНО ИЗ РЕШЕНИЙ:Если вы установите self.title="Независимо от того ...", вы увидите, что вместо "Назад" появится "Независимо от того ..." после нажатия кнопки new view controller.