2012-02-21 37 views
-1

我已經添加了NSTableView並正確設置了委託和數據源。如何在reloadData後立即重新繪製NSTableView

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 
    _items = [[NSMutableArray alloc] init]; 
    [_items addObject:@"ready"]; 
    [self.mainTableView reloadData]; 
} 

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { 
    return [self.items count]; 
} 

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 
    NSTableCellView *result = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self]; 
    result.textField.stringValue = [self.items objectAtIndex:row]; 
    return result; 
} 

還有用下面的代碼連接的NSButton:

- (IBAction)buttonPressed:(id)sender { 
    for (int i = 1; i <= 10; i++) { 
     NSString *item = [NSString stringWithFormat:@"%d", i]; 
     [_items replaceObjectAtIndex:0 withObject:item]; 
     [self.mainTableView reloadData]; 
     [NSThread sleepForTimeInterval:0.2f]; 
    } 
} 

程序正確運行並顯示在表視圖「準備就緒」,但是當我點擊該按鈕時,的內容表格視圖沒有立即改變。它改變了2秒後,只顯示最後一個數字 - 10.

我想要的是將NSTableViw的內容從1更改爲10,但不直接得到最終的數字。如何在reloadData之後立即重新繪製它?

回答

2

如何在reloadData後立即重新繪製它?

通過返回後reloadData。沒有其他辦法。代碼仍在運行時,您不能導致表視圖重繪。即使你使用另一個線程,它也不會按照你的設想工作。

如果要隨時間修改表,可以使用NSTimer定期修改數據,然後在每次更改後調用reloadData(或更好的情況下,reloadRowsAtIndexPaths:withRowAnimation:)。

用戶界面將永遠不會繪製在您的代碼中間。你必須回來讓它更新。


當您的代碼在主線程上運行時,UI不可能更新。有幾種方法在處理過程中提供用戶界面更新:

  • 做了一些工作,計劃做一個定時器或performSelector:withObject:afterDelay:,回報更多的工作,以使UI可以更新。這就是我上面所描述的。
  • 將您的工作分解爲小單位,並使用NSOperationQueue或GCD隊列進行計劃。如果你在主隊列上運行這些,這與第一個選項實際上是一樣的。你只是讓操作系統執行計劃。
  • 在後臺線程上運行處理並異步更新數據。定期更新UI。這對於簡單的進度計是很好的,但是如果你想讓UI更新處於特定點,很難同步。這引入了所有多線程代碼的頭痛問題,例如鎖定和atomicy。
+0

我試過你的方法,我想要的是處理一些數據,NSTableView可以顯示處理的進度。如果我使用NSTimer,一旦程序開始處理數據,那麼窗口沒有響應,直到處理完成。 – 2012-02-22 06:33:30

+0

感謝您的幫助,我發現問題,處理阻塞主線程來更新用戶界面,我將它移動到一個新的線程和程序工作正常。 – 2012-02-22 14:15:35

3
[NSThread sleepForTimeInterval:0.2f]; 

你在睡覺,想知道爲什麼事情似乎被推遲了?

[_items replaceObjectAtIndex:0 withObject:item]; 

您要更換的每個項目在數組中,不知道爲什麼只顯示最後一個項目?

你不應該睡覺主線程。刪除該行;發送reloadData將使表格視圖儘快重新顯示。

,填補了數組,這樣做:

for (int i = 1; i <= 10; i++) { 
    NSString *item = [NSString stringWithFormat:@"%d", i]; 
    [_items addObject:item]; 
} 
[self.mainTableView reloadData]; 

請注意,我已經搬到了reloadData外循環。在完成更新數據並準備好重新繪製表格視圖之前,您不應該發送該數據。

+0

對不起,也許我誤導了你,我想要的是將NSTableView的內容從1改爲10,但沒有全部列出。 – 2012-02-22 01:02:06

+0

我使用睡覺,因爲我想內容的變化更明顯。 – 2012-02-22 01:12:47

相關問題