чи можна програмно оновити заголовок / текст UIButton?


96

У мене є те UIButton, що при натисканні відкривається новий вид, у якому користувач може змінити деякі параметри. Коли подання відхилено, я хотів би оновити заголовок / текст, UIButtonщоб відобразити новий стан. Я телефоную:

[myButton setTitle: @"myTitle" forState: UIControlStateNormal];
[myButton setTitle: @"myTitle" forState: UIControlStateApplication];
[myButton setTitle: @"myTitle" forState: UIControlStateHighlighted];
[myButton setTitle: @"myTitle" forState: UIControlStateReserved];
[myButton setTitle: @"myTitle" forState: UIControlStateSelected];
[myButton setTitle: @"myTitle" forState: UIControlStateDisabled];

Але, здається, це ніколи не змінюється від початкового тексту / заголовка, як зазначено в IB.


2
Ви впевнені, що викликаний розміщений код? Ви розмістили BREAKPOINT, щоб довести це? Чи можете ви розмістити підпис свого делегата?
Пабло Санта-Крус

3
Як осторонь, я вважаю, що ви можете посилатись на кілька керуючих станів одночасно: [myButton setTitle: @ "myTitle" forState :( UIControlStateNormal | UIControlStateApplication | UIControlStateHighlight | ...)]; Зверніть увагу на використання бітового оператора АБО на відміну від логічного оператора АБО (||). Загалом, якщо ви маєте справу з такими державами, ви можете АБО їх разом із | оператор. Хтось мене виправить, якщо я грубо помиляюся. :)
CIFilter

Я хотів би, щоб у них був такий, як UIControlStateAll: D
taber

2
Побітна комбінація, здається, не працює для мене в iOS5.
Ехілон

Тут же питання. Побітні комбінації не працюють для мене на iOS5. / CC @LucasTizma
znq

Відповіді:


52

Чи є у вас кнопка, зазначена як IBOutlet, у вашому класі контролера перегляду, і чи правильно вона підключена як розетка у Interface Builder (ctrl перетягування з нової вихідної точки посилання до власника файлу та вибору об’єкта UIButton)? Зазвичай це проблема у мене, коли я бачу ці симптоми.


Редагувати: Хоча тут не так, щось подібне може статися, якщо ви встановите на кнопку атрибутовану назву , ви спробуєте змінити назву, а не атрибутивну назву.


4
Бінго, це було, дякую. Я справді бажаю, щоб Objective-C просто кинув NullPointerException у таких випадках, замість того, щоб мовчки робити вигляд, що це нормально, щоб відправити повідомлення на нульовий об'єкт. Це мене кусає майже щодня ... тьфу!
Джордж Армхолд

20
ObjC не "вдає", що все в порядку, щоб відправити повідомлення на нуль, тому що це нормально, якщо відправляти повідомлення на нуль ...
Jasarien

1
Справа тут не в нульовому покажчику. Проблема полягає в тому, що IB встановив екземпляр UIButton, на який у коді не посилається належним чином (через IBOutlet), тому ним ніколи не можна програмно маніпулювати.
CIFilter

112

Я вирішив проблему, просто встановивши параметр заголовка для UIControlStateNormal, і він автоматично працює в інших станах. Здається, проблема виникає при встановленні іншого UIControlState.

[myButton setTitle: @"myTitle" forState: UIControlStateNormal];


13

Я виявив ще одну проблему. Це може бути помилка, введена в iOS 5, але я подумав, що відзначу це для всіх, хто стикається з нею.

Якщо ви не встановите будь-який текст за замовчуванням для кнопки в XIB, жоден текст не з’явиться, якщо встановити його програмно. І якщо ви все-таки встановите текст у XIB, будь-який текст, який ви згодом призначите кнопці програмно, буде скорочений до розміру тексту за замовчуванням.

І нарешті, якщо ви показуєте подання кнопкою, а потім викликаєте інший вигляд (наприклад, ActionSheet), а потім відхиляєте його, текст, який ви присвоїли кнопці програмно, буде стертий, а підпис кнопки повернеться до того, що ви встановили вгору в XIB.


1
Я помітив усі три способи поведінки, і це, безумовно, дратує.
Блоха

2
У мене була проблема з усіченням (зміна тексту на щось більш програмне), тому я ставлю зайві пробіли в кінці тексту, щоб «зарезервувати» цей простір, коли я зміню текст на довше слово. Це спрацювало для мене.
mattorb

2
Здається, виправлення цього полягає у використанні методу [_button setTitle: @ "title" forState: UIControlStateNormal]; замість безпосереднього доступу до властивості _button.titleLabel.text. Дотримуйтесь виклику методу, і ви, мабуть, отримаєте те, що хочете.
Rymnel

12

Незважаючи на те, що проблема з кофеїновою комою була вирішена, я хотів би запропонувати ще одну потенційну причину, через яку назва не відображається на кнопці UIB.

Якщо ви встановите зображення для кнопки UIB, використовуючи

- (void)setImage:(UIImage *)image forState:(UIControlState)state

Він може охоплювати заголовок. Я зрозумів це важко і уявляю, що деякі з вас в кінцевому підсумку читають цю сторінку з тієї ж причини.

Замість цього використовуйте цей метод

- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state

для зображення кнопки та заголовка це не вплине.

Я перевірив це за допомогою програмно створених кнопок та кнопок, створених у .xib



4

Виявляється, документи відповідають вам! Кнопка UIB буде ігнорувати зміну заголовка, якщо у нього вже є Атрибутивний рядок для використання (мабуть, за замовчуванням ви отримуєте при використанні конструктора інтерфейсу Xcode).

Я використав наступне:

[self.loginButton 
     setAttributedTitle:[[NSAttributedString alloc] initWithString:@"Error !!!" attributes:nil] 
     forState:UIControlStateDisabled];
[self.loginButton setEnabled:NO];

3

Ще одна можлива причина:

Якщо ви спробуєте встановити заголовок кнопки в (id)initWithNibName: ...методі, тоді ви властивість кнопки все одно буде нульовим. Він ще не призначений UIButton.

Ви повинні бути впевнені, що ви налаштовуєте свої кнопки таким способом, як (void)viewWillLoadабо (void)viewWillAppear, але ви, мабуть, не хочете встановлювати їх так пізно (void)viewDidAppear.


2

Іноді це може дуже ускладнитися. Найпростіший спосіб - « оновити » перегляд кнопок!

//Do stuff to your button here.  For example:

[mybutton setEnabled:YES];

//Refresh it to new state.

[mybutton setNeedsDisplay];

1

У мене постійно виникали проблеми з цим, єдиним рішенням було додати зображення та мітку як підпрогляди до кнопки ui. Потім я виявив, що основною проблемою було те, що я використовував UIBкнопку із заголовком: Attributed. Коли я змінив його на Звичайний, просто встановлення titleLabel.text зробило свою справу!


1

@funroll абсолютно прав. Тут ви можете побачити, що вам знадобиться Переконайтеся, що функція працює лише в основному потоці . Якщо ви не хочете мати справу з потоками, ви можете зробити так, наприклад: створити NSUserDefaults, а в умові перевірки ViewDidLoad було натиснуто кнопку в іншому поданні чи ні (в іншому поданому наборі в NSUserDefaults потрібна інформація) і залежно від встановлених умов потрібна назва для ваш UIButton, так що [yourButton setTitle: @ "Title" forState: UIControlStateNormal];


Це було мені дуже корисно .. виявляється, якщо ви зателефонуєте setTitle та setNeedsDisplay з фонової нитки, подання оновиться значно пізніше.
user1111828

0

Переконайтеся, що ви в основній темі.

Якщо ні, він все одно збереже текст кнопки. Він буде там, коли ви оглянете об’єкт у налагоджувачі. Але це фактично не оновить подання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.