Изменение заголовка UIBarButtonItem не работает

Как я могу изменить название UIBarButtonItem? У меня есть следующий код, который вызывается при нажатии кнопки редактировать на моем UINavigationBar.

-(void)editButtonSelected:(id)sender {
    NSLog(@"edit button selected!");
    if(editing) {
        NSLog(@"notediting");
        [super setEditing:NO animated:NO];
        [tableView setEditing:NO animated:NO];
        [tableView reloadData];
        [rightButtonItem setTitle:@"Edit"];
        [rightButtonItem setStyle:UIBarButtonItemStylePlain];
        editing = false;
    }
    else {
        NSLog(@"editing");
        [super setEditing:YES animated:YES];
        [tableView setEditing:YES animated:YES];
        [tableView reloadData];
        [rightButtonItem setTitle:@"Done"];
        [rightButtonItem setStyle:UIBarButtonItemStyleDone];
        editing = true;
    }
}

Кнопка edit меняет цвет (поэтому строка, задающая стиль, работает), однако строка, задающая заголовок кнопки, не работает.


person CodeGuy    schedule 27.05.2011    source источник


Ответы (8)


Я сделал следующее, чтобы динамически изменить заголовок UIBarButtonItem. В этой ситуации я не использую UIViewTableController и не могу использовать стандартный editButton. У меня есть представление с tableView, а также другие подпредставления, и я хотел эмулировать поведение ограниченного UIViewTableController.

- (void)InitializeNavigationItem
{
    NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:2];
    UIBarButtonItem* barButton;

    barButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                                                              target:self 
                                                              action:@selector(addNewItem:)];
    barButton.style = UIBarButtonItemStyleBordered;
    [array addObject:barButton];

    // --------------------------------------------------------------------------------------

    barButton = [[UIBarButtonItem alloc] initWithTitle:@"Edit" style:UIBarButtonItemStyleBordered
                                                              target:self 
                                                              action:@selector(editMode:)];
    barButton.style = UIBarButtonItemStyleBordered;
    barButton.possibleTitles = [NSSet setWithObjects:@"Edit", @"Done", nil];
    [array addObject:barButton];

    self.navigationItem.rightBarButtonItems = array;
}

- (IBAction)editMode:(UIBarButtonItem *)sender
{
    if (self.orderTable.editing)
    {
        sender.title = @"Edit";
        [self.orderTable setEditing:NO animated:YES];
    }
    else
    {
        sender.title = @"Done";
        [self.orderTable setEditing:YES animated:YES];
    }
}

Обратите внимание, что я не использовал кнопку UIBarButtonSystemItemEdit barButton, вы не можете вручную изменить имя этой кнопки, что имеет смысл.

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

Если вы используете раскадровку/XIB для создания/настройки этих кнопок, убедитесь, что для идентификатора элемента кнопки панели установлено значение «Пользовательский» для кнопки, для которой вы хотите управлять заголовком.

person Seamus    schedule 13.02.2012
comment
Я думаю, что вызов barButton.possibleTitles излишен. Я обнаружил, что это сработало, просто установив тип вызывающего абонента в методе editMode и используя sender.title = @something - person Simon Curd; 22.09.2013
comment
Спасибо @Seamus! Хитрость для меня заключалась в том, чтобы НЕ использовать кнопку «Редактировать», которая обычно работает в UITableViewController. Я считаю, что, поскольку это была родная кнопка «Редактировать», она не позволяла мне изменить заголовок. Я установил свой на Custom. - person kbpontius; 28.05.2015
comment
+1 к possibleTitles. Странно, что вы должны объявлять возможности заранее, но это, похоже, решило это для меня. - person mylogon; 07.05.2017
comment
If you are using a Storyboard/XIB to create/set these buttons, ensure that the Bar Button Item Identifier is set to Custom for the button which you'd want to control the title for. Это то, что я искал. Спасибо! - person Phontaine Judd; 28.10.2019

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

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

person Mark Bridges    schedule 04.02.2013
comment
Супер простое решение - отлично работает. Я использую раскадровки, поэтому даже с многоцелевой кнопкой редактирования вы можете перехватывать касания пользователя с помощью - (BOOL) shouldPerformSegueWithIdentifier: и выполнять пользовательские действия. Огромное спасибо за это простое (и то, что должно было быть очевидным) решение! - person Mike Critchley; 30.01.2016
comment
да, пользовательский тип позволит вам получить доступ к заголовку - person Edward Ashak; 24.03.2016

В моем случае то, что предотвратило отображение заголовка, заключалось в том, что в xib я выбрал свойство «идентификатор» элемента «Панель» как «Отмена».

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

Я попытался установить свойство title еще до назначения кнопки панели навигации, но заголовок не обновлялся.

Я сделал это так:

введите здесь описание изображенияИ все заработало, как я и хотел.

person Joe M    schedule 17.02.2015
comment
Это правда, Спасибо! - person daniel kilinskas; 26.04.2016

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

person Deepak Danduprolu    schedule 27.05.2011
comment
Точно! например: Достаточно закодировать: UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@Done style:UIBarButtonItemStyleDone target:self action:@selector(someMethod)]; для создания кнопки «Готово». - person Oscar Salguero; 02.03.2012
comment
Да, он говорит, что вы должны установить заголовок перед добавлением, но в чем тогда смысл свойства возможных заголовков? - person Gordon Dove; 26.10.2012
comment
Я добавил кнопку панели программно и установил свойство possibleTitles. У меня не было проблем с изменением свойства title на лету — как говорит Гордон — какой смысл в свойстве possibleTitles, если заголовок нельзя изменить? - person wcochran; 23.06.2014
comment
possibleTitles — предоставить альтернативы, когда на панели навигации больше или меньше места (например, альбомная или портретная, iPhone 4, iPhone 6 Plus и iPad). - person jrc; 15.10.2015

На самом деле, если все, что вы хотите, при переключении между «Редактировать» и «Готово», просто используйте self.navigationItem.rightBarButtonItem = self.editButtonItem;

Он справится с этим переходом для вас

person gyan    schedule 19.01.2015
comment
Это переключит кнопку, а не изменит заголовок, как задает вопрос. - person Steve Buzonas; 20.01.2015
comment
Я не знаю, как Apple реализует этот editButtonItem, но он ведет себя как одна кнопка, переключающаяся между Edit и Done. Если вы хотите изменить заголовок на что-то другое, это не сработает. Но из кода, опубликованного OP, это именно то, что ему нужно. - person gyan; 20.01.2015
comment
Если он использует UIBarButtonSystemItemEdit, то да, Apple использует множество неизменяемых объектов, и имеет смысл не иметь возможности изменить заголовок с «Редактировать» на «Готово» в классе со словом «редактировать». - person Steve Buzonas; 20.01.2015

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

- (void)setNavigationButtonAsEdit
{
    UIBarButtonItem* editButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Edit", @"")
                                                                   style:UIBarButtonItemStylePlain
                                                                  target:self
                                                                  action:@selector(editButtonPressed:)];

    self.navigationItem.rightBarButtonItems = [NSArray arrayWithObject:editButton];
}

- (void)setNavigationButtonAsDone
{
    UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Done", @"")
                                                                   style:UIBarButtonItemStylePlain
                                                                  target:self
                                                                  action:@selector(editButtonPressed:)];
    self.navigationItem.rightBarButtonItems = [NSArray arrayWithObject:doneButton];
}

А затем создайте IBAction для обработки нажатия кнопки:

- (IBAction)editButtonPressed:(id)sender
{
    NSString* buttonText = [sender title];
    if ([buttonText isEqualToString:NSLocalizedString(@"Edit",@"")])
    {
        [self setNavigationButtonAsDone];
    }
    else
    {
        [self setNavigationButtonAsEdit];
    }
}
person Scott Allen    schedule 24.09.2013

Свифт 3.0, 3.2 или 4.0

Если ваш пользовательский ViewController, содержащий объект tableView, следует протоколам UITableViewController Delegate и Datasource, вы можете добавить системный editBarButtonItem к своим navigationItem.leftBarButtonItem(s) или navigationItem.rightBarButtonItem(s) со следующим кодом:

func setupTableView() {
    tableView.delegate = self
    tableView.dataSource = self
    navigationItem.rightBarButtonItem = editButtonItem
    editButtonItem.action = #selector(CustomViewController.editTableView(_:))
    
}

@objc func editTableView(_ sender: UIBarButtonItem) {
    tableView.isEditing = !tableView.isEditing
    if tableView.isEditing {
        sender.title = "Done"
    } else {
        sender.title = "Edit"
    }
}
person umarqattan    schedule 10.08.2017

Пытаться:

UIButton *rightButton;
rightButton = (UIButton*)self.navigationItem.rightBarButtonItem.customView;
[rightButton setTitle:@"Done" forState:UIControlStateNormal];

Потому что rightBarButtonItem.customView == “the button your added”.

person dadoftutu    schedule 25.03.2014
comment
Кнопка, которую вы добавили? Что это обозначает? - person Alex Zavatone; 26.09.2017