2011-07-26 5 views
33

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

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 для записи звука и загрузки записанного файла здесь. Ничего больше. Не использовал нить.

+0

Где вы обновляете текст (какой метод)? Он должен находиться в одном потоке (см. Http://stackoverflow.com/questions/6000741/cant-redraw-uilabel-after-updating-text). –

+0

@Ben: aint, что для monotouch? Кроме того, я внутри одной и той же темы, просто еще одна функция! – Ahsan

+0

Я полностью пропустил это вопрос MonoTouch, но я нашел аналогичную проблему о том, что вам нужно быть в одном потоке на форуме Mac, который использовал performSelectorOnMainThread (http://forums.macrumors.com/showthread.php?t=463200) , поэтому я просто задавался вопросом, откуда вы его звонили. –

ответ

47

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

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

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

+0

Спасибо за предложение. Вот что я делаю внутри приложения/представления. Я использую AVFoundation для записи некоторого звука и использования класса ASIHTTP для загрузки записанный звук ... ничего особенного .... В функции, которая загружает файл (пользовательская функция), я изначально пишу код для изменения метки. Ничего не работает. Я даже попытался выполнитьSelectorOnMainThread ... не работал. – Ahsan

+0

больше похожа на вашу загрузку в основной теме – bshirley

+1

[[NSRunLoop mainRunLoop] .. thingy работал .... другой альтернативный не сделал ... спасибо кучу .. :) ты только что сделал мой день! – Ahsan

48

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

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

Простой и легкий. Спасибо! –

+0

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

2

У меня был 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/ для более подробного объяснения

3

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

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

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

Смежные вопросы