在iOS中设置标签文字时遇到问题
我有一个连接的UILabel
@property (strong, nonatomic) IBOutlet UILabel *label;
还有一个Action,是由button触发的
- (IBAction)buttonPressed:(UIButton *)sender;
当按下button,我想更新标签显示运行秒数达3分钟,所以我
- (IBAction)buttonPressed:(UIButton *)sender { for (int i =0; i < 180; ++i) { [label setText:[NSString stringWithFormat:@"%d", i]]; sleep(1); } }
确认,方法被调用,计时器正在滴答滴答。标签文本却没有改变。 请问我做错了什么?
sleep()
不允许UI线程自行更新。
这是一个使用GCD的示例,它与您的原始代码非常相似。 注意:有更好的方法来做到这一点(请参阅: dispatch_after()
)。
- (IBAction)buttonPressed:(UIButton *)sender { [label setText:[NSString stringWithFormat:@"%d", 0]]; dispatch_queue_t queue = dispatch_queue_create("com.test.timmer.queue", 0); dispatch_async(queue, ^{ for (int i = 1; i < 180; ++i) { sleep(1); dispatch_async(dispatch_get_main_queue(), ^{ [label setText:[NSString stringWithFormat:@"%d", i]]; }); }); }
你的睡眠()是在主线程中,你的视图不能刷新,你可以使用NSTimer来做到这一点。
- (void)update { [label setText:[NSString stringWithFormat:@"%d", i]]; i++; if(i>=100) { [timer invalidate]; } } - (IBAction)buttonPressed:(UIButton *)sender { timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES]; [timer fire]; }
您必须退回到您的runloop以允许控制刷新。 你可能应该使用一个NSTimer,每隔一秒钟就会发生,而不是一个紧密的循环。
虽然不是真的推荐,但是如果你在setText之后调用它,下面的方法也可以工作:
[[NSRunLoop currentRunLoop] acceptInputForMode:NSDefaultRunLoopMode beforeDate:nil];
所有与UI相关的事情都在主线程中完成。 强制你的运行时间睡在主线程将从字面上冻结你的用户界面。 做180次,你有一个沮丧的最终用户。