2010-08-31 117 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"; 
}