2016-01-23 244 views
0

我將異步加載圖像並將其設置爲表格視圖單元格。問題是我爲我的單元格使用自動佈局,所以我希望表格視圖在設置圖像後重繪單元格。重新繪製表格視圖單元格而不調用cellForRowAtIndexPath

tableView.rowHeight = UITableViewAutomaticDimension 
tableView.estimatedRowHeight = 300.0 

在通常情況下,我會使用tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade),但這種呼籲cellForRowAtIndexPath方法,而這又要求我的圖像下載方法。

我試着打電話給tableView.layoutIfNeeded(),cell.layoutIfNeeded(),cell.setNeedsLayout(),沒有什麼幫助。

我的問題是如何重繪表格視圖單元而不調用cellForRowAtIndexPath方法?

回答

0

如果您使用的是UIImageView來顯示圖像,則不需要重繪該單元格,只需在圖像完成下載時設置圖像屬性即可。

如果您自己在自定義的UIView子類上繪製圖像,則可以在該視圖上調用setNeedDisplay方法,該方法將視圖標記爲髒,並將在下一個週期重繪。

但是,最好的方法是改善cellForRowAtIndexPath:並在模型對象中設置downloading標誌,並且只有在未設置該標誌時纔開始下載。

2

這裏存在的根本問題是您下載圖像的方式。您應該在代碼中進行一些記錄,並跟蹤哪些圖像已經下載或已經下載。根據這一點,您可以決定是否應該開始新的下載。 不要試圖繞過這個,因爲這會在以後給你帶來很多痛苦(我從經驗中知道)。 最好的方法是擁有某種數據對象,以及另一個可以下載的對象。然後,只要下載完成,該對象就會更新此映像的正確數據對象。然後這個下載者應該告訴你的數據源這個數據對象已經更新了。作爲響應,您的dataSource可以重新加載該數據對象的indexPath。通過這種方式,您的數據源永遠不用擔心下載,並且可以簡單地檢查數據對象並使用它來設置單元格中的值。如果有圖像下載,它將使用它,否則沒有圖像(或某個佔位符可能)。

現在,您可以保留包含作爲鍵的單元格的URL或名稱或索引路徑的@(YES)或@(NO)值的字典屬性。然而,這種方法是天真的,因爲它不會很可維護或可移植(對其他viewControllers或您的應用程序的部分),並且索引路徑和圖像之間不容易轉換。請記住,tableViewCells永遠不能用作使用某些邏輯的數據源:它們是您擁有其他邏輯將數據放置到其上的終點。這是因爲它們被重複使用,基本上不能被信任永遠處於某個特定的位置。基於您在indexPaths上的所有工作。 (並使用tableview來獲取單元格的indexPath)。

所以,現在你可以在cellForRowAtIndexPath:

NSString * imageURL = .... 
NSNumber * downloading = self.imageDownloads[imageURL]; 
if (!downloading.boolValue) 
{ 
    self.imageDownloads[imageURL] = @(YES); 
    // start your download 
} 

- (void) imageDownloadedForURL: (NSString *) imageURL 
{ 
    self.imageDownloads[imageURL] = @(YES); // this is redundant 
    [self.tableView reloadRowAtIndexPaths: @[indexPathForThisImage]]; 
} 
- (void) imageDownloadForULRFailed: (NSString *) imageURL 
{ 
    self.imageDownloads[imageURL] = @(NO); 
    // trigger a new download? (but be careful not to DDOS your server this way) 
} 
相關問題