UILabel 文本未更新
Posted
技术标签:
【中文标题】UILabel 文本未更新【英文标题】:UILabel text not being updated 【发布时间】:2011-07-26 19:33:26 【问题描述】:我无法更改 UILabel 文本。 viewDidLoad 里面的 UILabel 的代码是:
startLabel=[[UILabel alloc] initWithFrame:CGRectMake(75, 395, 200, 30)];
startLabel.text=@"Recording Sound ...";
startLabel.backgroundColor=[UIColor clearColor];
startLabel.textColor=[UIColor whiteColor];
startLabel.font=[UIFont boldSystemFontOfSize:17];
[self.view addSubview:startLabel];
稍后,如果我想用以下代码更改文本的标签,它不会在应用程序上更改:
startLabel.text=@"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
类来录制声音并在此处上传录制的文件。没有其他的。没有使用任何线程。
【问题讨论】:
你在哪里更新文本(什么方法)?它需要在同一个线程上(参见:***.com/questions/6000741/…)。 @Ben:那不是单点触控吗?另外,我在同一个线程中,只是另一个函数! 我完全错过了作为 MonoTouch 的问题,但我发现了一个类似的问题,即需要在使用 performSelectorOnMainThread (forums.macrumors.com/showthread.php?t=463200) 的 Mac 论坛中的同一个线程上,所以我只是想知道你在哪里是从那里调用它的。 @Ben : 不.. 不工作.. :(.. 还有其他建议吗? 【参考方案1】:您可能会遇到上述 cmets 中提到的线程问题。如果您有一个在主线程上运行并执行某些活动(例如搜索数据库)的方法,则在运行循环获得控制之前,您对 UI 所做的更新不会被提交。因此,如果您在主线程上执行了一个很长、很耗时的任务,请在设置标签文本后运行此代码:
- (void)doSomethingTimeConsuming
... consume some time ...
... set text of label ...
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
... continue long operation ...
这应该会清除您所做的任何 UI 更改。尽管这可能是一个明智且实用的 hack,但它并没有击败替代方案。我强烈建议您在后台线程上执行应用程序的耗时任务,并使用performSelectorOnMainThread:withObject:waitUntilDone:
通过主线程更新 UI。请参阅 Apple 在ios Thread Management 上的页面。
【讨论】:
感谢您的建议。这是我在应用程序/视图中所做的事情。我正在使用 AVFoundation 录制一些声音并使用 ASIHTTP 类上传录制的声音。没什么特别的......在上传文件的函数(自定义函数)中,我最初正在编写代码来更改标签。没有任何效果。我什至尝试过 performSelectorOnMainThread ...没有工作。您认为录制/上传是否有资格作为单独的线程?请建议我能做什么。谢谢。 [[NSRunLoop mainRunLoop] .. 东西有效.. 另一个替代品没有... 非常感谢.. :) 你让我开心! 谢谢,我遇到了类似的问题,但performSelectorOnMainThread:withObject:waitUntilDone:
解决方案对我来说效果很好。将问题追溯到这样一个事实,即从设置为在异步 URL 请求完成后运行的代码块触发了 UI 更新(但未显示)。我什至可以建议使该解决方案在您的答案中更加突出,以免人们错过它,因为它目前是公认的答案?
即使 [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0]];
也为我工作(时间间隔为 0)【参考方案2】:
在我的情况下,正在更新的函数是从线程上的触摸识别器调用的,但是我在函数中更改标签文本属性值的位置将其放回主线程:
dispatch_async(dispatch_get_main_queue(), ^
[self.someLabel setText:someString];
);
【讨论】:
简单易行。谢谢! 我试图从通知中心调用的方法刷新文本,这解决了问题,谢谢!【参考方案3】:我有一个 UILabel,它显示了一个不会更新到 UIViewController 上的新级别编号的级别编号。我能找到的唯一可行的解决方案是在拥有 UILabel 的视图控制器的主线程上调用 setNeedsDisplay
-(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/了解更详细的解释
【讨论】:
【参考方案4】:我的想法有点出人意料,虽然是合理的——只是没有人想太多。
当我收到我在其他地方解雇的NSNotification
时,我应该更新UILabel
。但是,通知是从后台线程触发的,因此即使是更新标签文本的侦听器方法也会在后台触发。
如果您依赖 NSNotification
来更新标签或您的任何视图,请从主 UI 线程中触发 NSNotification
。
【讨论】:
以上是关于UILabel 文本未更新的主要内容,如果未能解决你的问题,请参考以下文章
调整 UITableViewCell 中的 UILabel 大小在渲染前未更新