2010-02-23 163 views
24

我有一個UITableview,我加載數據異步,因此tableview可能會顯示沒有數據。
我已經厭倦了ReloadData方法,但tableview保持爲空,直到我滾動tableview,突然出現數據。
同樣的事情發生時,我加載一個tableview作爲詳細視圖和項目之間切換,previoud項目數據首先出現,只要我在表格視圖中滾動它顯示正確的數據。
我的猜測是ReloadData方法工作得很好,但我需要以某種方式重繪tableview,有關如何解決這個問題的任何建議?更新數據後重繪UITableView異步

/Jimmy

+0

通常reloadData方法刷新tableview的視圖。你可以把你的TableViewController代碼的樣本? – 2010-02-23 23:32:23

回答

53

你說你是異步填充的內容,但你調用reloadData在主線程的上下文? (而不是通過用於填充內容的線程)

目標C

[yourUITableView performSelectorOnMainThread:@selector(reloadData) 
            withObject:nil 
           waitUntilDone:NO]; 

夫特

dispatch_async(dispatch_get_main_queue(), { self.tableView.reloadData() }) 

MonoTouch的

InvokeOnMainThread(() => this.TableView.ReloadData()); 
+7

感謝解決了它=) 單點觸摸的解決方案是: InvokeOnMainThread(()=> this.TableView.ReloadData()); – 2010-02-24 11:37:20

+0

@yonel我和JimmyEngtröm有同樣的問題,我真的希望你所說的會做,但唉,我仍然有這個問題。在我更新它所使用的基礎數據陣列後,我無法找到刷新UITableView的方法。 – 2011-10-11 07:00:00

+0

@ MasonG.Zhwiti:在您的表數據源的numberOfRowsInSections方法中設置斷點,並檢查它是否在reloadData之後進入它。然後檢查你在這裏返回的行數,如果它不是0,那麼它將調用cellForRowAtIndex。 – yonel 2011-10-11 07:14:07

2

我想它沒有重新加載。

滾動時的細胞出來的畫面,然後...

tableView: cellForRowAtIndexPath:

...將被調用。所以它會被重新加載。

我想UITableView變量沒有驗證。

如果你使用UITableView作爲主視圖,你可以試試這個。

[self.view reloadData];

[self.tableView reloadData];

4

Yonels答案是完美的,當你的看法是目前可見的用戶(如:用戶按下一個重載按鈕,填入您UITableView)。

但是,如果你的數據異步加載和你UITableView在更新過程中是不可見的(例如:在另一個視圖中將數據添加到UITableView,稍後由userinput顯示UITableView),只需覆蓋UITableViewControllerviewWillAppear方法。

- (void)viewWillAppear:(BOOL)animated{ 
[super viewWillAppear:animated]; 
[self.tableView reloadData]; 
} 

的正面效果是,你只UITableView它重新加載的數據,一旦當用戶真正想要的看到它,添加新項目時,不。

2

今天我有類似的問題(故事板iOS 7.0中)。 我在UIViewController裏面使用table View。當視圖加載的時候一切正常,所有代表都被召集了。但是;當基礎數據源(在我的情況下,數組)被修改;可見的表格行沒有被更新。它們被更新;只有當我滾動表視圖。

試了一下;在主線程上調用reloadData;在ViewWillAppear中調用reload;沒有工作。

我發現的問題;是因爲我沒有在故事板上建立聯繫;對於帶有參考Outlet的表視圖。dataSource和delegate已被設置。 我不認爲這可能是問題;因爲一開始一切工作都很好。

希望它可以幫助別人。我有一些可怕的時間來找到這個。

0

經過在yonel的解決方案中有些天真的複製,並稱它很好,我意識到調用performSelectorOnMainThread:withObject:waitUntilDone:修復了症狀,但不是問題。更大的問題是,您仍然在異步或後臺線程的上下文中進行UI更新。

這就是看起來像我的代碼:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL); 
dispatch_async(queue, ^{ 

    // Make API call 
    // Retrieve data, parse JSON, update local properties 
    // Make a call to reload table data 

}); 

當它應該是這樣的:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL); 
dispatch_async(queue, ^{ 

    // Make API call 
    // Retrieve data, parse JSON, update local properties 

    dispatch_async(dispatch_get_main_queue(), ^{ 
    // Now make the call to reload data and make any other UI updates 
    [self.tableView reloadData] 
    }); 

}); 

如果您需要做的唯一的事就是調用[self.tableView reloadData]它可能是罰款使用performSelectorOnMainThread:withObject:waitUntilDone:,因爲它實現了相同的目標,但您也應該認識到大圖中發生的事情。此外,如果您正在執行更多的UI工作而不是重新加載表,那麼所有代碼​​也應該放在主隊列中。

參考:A concise example使用GCD和管理背景與主線程。