我正在尝试创建一个UILabel,它会在用户等待时通知用户发生了什么。但是,UILabel总是会延迟其文本更新,直到系统再次进入空闲状态。
过程:
[infoLine performSelectorOnMainThread:@selector(setText:) withObject:@"Calculating..." waitUntilDone:YES];
[distanceManager calc]; // Parses a XML and does some calculations
[infoLine performSelectorOnMainThread:@selector(setText:) withObject:@"Idle" waitUntilDone:YES];
不应该等待“立即”这样做吗?
答案 0 :(得分:4)
如果您在主UI线程上执行此操作,请不要使用waitUntilDone。在完整视图上执行setText,setNeedsDisplay,设置NSTimer以在1毫秒后启动您要执行的操作,然后从函数/方法返回。您可能必须将计算分解为可以由计时器单独调用的chuck,也可以是具有switch语句的状态机(select chunk,execute chunk,increment chunk index,exit),由计时器调用直到完成。 UI将在您的计算块之间跳转并更新内容。因此,请确保您的块很短(我使用15到200毫秒)。
答案 1 :(得分:0)
是waitUntilDone
会立即发生setText:
,但设置标签的文字并不意味着屏幕会立即更新。
您可能需要call -setNeedsDisplay
或甚至让主运行循环勾选一次,然后才能更新屏幕。
答案 2 :(得分:0)
这是我添加到UIViewController
的子类的有用功能。它在下一个运行循环中执行选择器。它有效,但你认为我应该使NSTimer *timer
成为一个实例变量,因为这个方法可能不止一次被调用。
- (void)scheduleInNextRunloopSelector:(SEL)selector {
NSDate *fireDate = [[NSDate alloc] initWithTimeIntervalSinceNow:0.001]; // 1 ms
NSTimer *timer = [[NSTimer alloc]
initWithFireDate:fireDate interval:0.0 target:self
selector:selector userInfo:nil repeats:NO];
[fireDate release];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[timer release];
}
答案 3 :(得分:0)
使用performSelector:(SEL) withObject:(id) afterDelay:(NSTimeInterval)
:
self.infoLine.text = @"Calculating...";
[self performSelector:@selector(likeABoss) withObject:nil afterDelay:0.001];
//...
-(void) likeABoss {
// hard work here
self.infoLine.text = @"Idle";
}