2010-08-31 88 views
3

我正在尝试创建一个UILabel,它会在用户等待时通知用户正在进行的操作。但是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]; 

不应该waitUntilDone做到这一点 “马上”?

+0

你尝试到指定waitUntilDone为NO? – vodkhang 2010-08-31 08:30:58

+0

是的,也尝试过... – ciffa 2010-08-31 08:44:18

+0

你是在主UI线程还是从其他线程执行此操作? – hotpaw2 2010-08-31 08:49:03

回答

4

如果您在主UI线程上执行此操作,请勿使用waitUntilDone。在完整视图上执行setText,setNeedsDisplay,设置一个NSTimer,以便在1毫秒后启动下一步开始的操作,然后从函数/方法返回。你可能不得不将计算分割成可由计时器单独调用的卡盘,也许是一个带有切换语句的状态机(选择块,执行块,增量块索引,退出),直到它完成为止。用户界面将在您的计算块之间跳转并更新内容。所以确保你的块很短(我使用15到200毫秒)。

+0

它的工作原理!谢谢! – ciffa 2010-08-31 09:05:32

+0

不客气。 – hotpaw2 2010-08-31 09:13:07

+0

请发布示例代码,了解如何“设置NSTimer启动1毫秒后的下一次启动操作”。谢谢!另外,我希望它在下一次运行循环中被解雇。你怎么知道1毫秒是使用时间? – ma11hew28 2011-05-06 15:16:25

0

waitUntilDone使setText:立即发生,但设置标签的文本并不意味着屏幕立即更新。

您可能需要call -setNeedsDisplay甚至让主运行循环在屏幕更新之前打勾一次。

+0

我试过使用[infoLine setNeedsDisplay];但没有任何反应。如何在运行distanceManager之前等待主循环打勾一次? – ciffa 2010-08-31 08:35:33

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]; 
} 
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"; 
}