Подтвердить что ты не робот

Текст UILabel не обновляется

Я не могу изменить текст UILabel. Код для UILabel внутри viewDidLoad:

startLabel=[[UILabel alloc] initWithFrame:CGRectMake(75, 395, 200, 30)];
[email protected]"Recording Sound ...";
startLabel.backgroundColor=[UIColor clearColor];
startLabel.textColor=[UIColor whiteColor];
startLabel.font=[UIFont boldSystemFontOfSize:17];

[self.view addSubview:startLabel];

Позже, если я хочу изменить метку текста со следующим кодом, он не изменяется в приложении:

[email protected]"Searching Database ...";

или

[startLabel setText:@"Searching Database ..."];

UILabel не пуст, я распечатал его во время отладки, и он показывает:

(gdb) po startLabel
<UILabel: 0x2c1a30; frame = (75 395; 200 30); text = 'Searching Database ...'; 
clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x2ae8f0>>

Итак, текст метки изменяется внутри UILabel, но не обновляется на экране.

Может кто-нибудь любезно сообщить мне, что Мне здесь не хватает? Спасибо.

Изменить 1: Я пробовал performSelectorOnMainThread: - не работал у меня. Изменить 2: Я использую классы AVFoundation и ASIHTTP для записи звука и загрузки записанного файла здесь. Ничего больше. Не использовал нить.

4b9b3361

Ответ 1

Возможно, вы столкнулись с проблемой потоковой передачи, упомянутой в комментариях выше. Если у вас есть метод, который работает в основном потоке и выполняет некоторые действия (например, поиск в базе данных), обновления, которые вы вносите в пользовательский интерфейс, не будут выполняться до тех пор, пока цикл выполнения не получит контроль. Итак, если у вас есть долгая, трудоемкая задача, идущая в основном потоке, запустите этот код после установки текста метки:

- (void)doSomethingTimeConsuming
    ... consume some time ...
    ... set text of label ...
    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
    ... continue long operation ...
}

Это должно скрыть любые изменения пользовательского интерфейса, которые вы сделали. Хотя это может быть разумным и функциональным взломом, он не превзойдет альтернативы. Я настоятельно рекомендую вам выполнять ваши задачи, требующие много времени, в фоновом потоке и обновлять интерфейс через основной поток с помощью performSelectorOnMainThread:withObject:waitUntilDone:. См. Страницу Apple в Управление потоками iOS.

Ответ 2

В моем случае функция, которая была обновлена, вызывалась из сенсорного распознавателя в потоке, но место в функции, где я меняю значение свойства текста метки, я возвращаю его в основной поток:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.someLabel setText:someString];
});

Ответ 3

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

Я должен обновить UILabel, когда получаю NSNotification, который я запускал где-то в другом месте. Однако уведомление было уволено из фонового потока, поэтому даже методы прослушивателя, которые обновляют текст ярлыков, запускаются в фоновом режиме.

Если вы полагаетесь на NSNotification, чтобы обновить ярлык или любое ваше представление, выполните огонь NSNotification из основного потока пользовательского интерфейса.

Ответ 4

У меня был UILabel, показывающий номер уровня, который не обновлялся бы до нового уровня на UIViewController. Единственное жизнеспособное решение, которое я смог найти, заключалось в том, чтобы вызвать setNeedsDisplay в основном потоке контроллера вида, который владел UILabel

-(void)changeLevelLabel:(int)theLevel {
dispatch_async(dispatch_get_main_queue(), ^{
    self.levelLabel.text = [NSString stringWithFormat:@"%d",theLevel];
    [self.levelLabel setNeedsDisplay];
});

}

Подробнее см. http://iosdevelopmentjournal.com/blog/2013/01/16/forcing-things-to-run-on-the-main-thread/