這個問題沒有爲變化的圖像大小指定所需的行爲。單元格應該適合高度還是單元格內的圖像視圖(看起來像代碼中的按鈕)?
但是我們應該暫時擱置這個問題並且研究代碼中更嚴重的問題:它會發出一個來自cellForRowAtIndexPath
的無保護的網絡請求。結果,(a)用戶來回滾動會產生許多多餘的請求,並且(b)用戶快速長時間滾動會產生一個請求,當啓動它的單元消失時,該請求會被滿足 - 作爲單元重用換另一行。
爲了解決(a),數據源應該緩存提取的圖像,並只請求那些沒有收到的圖像。爲了解決(b),完成塊不應直接指向單元。
一個簡單的緩存是這樣的:
@property(strong,nonatomic) NSMutableDictionary *images;
// initialize this when you initialize your model
self.images = [@{} mutableCopy];
// move the network code into its own method for clarity
- (void)imageWithPath:(NSString *)path completion:(void (^)(UIImage *, NSError *))completion {
if (self.images[indexPath]) {
return completion(self.images[indexPath], nil);
}
NSURL *imageURL = [NSURL URLWithString:path];
NSURLRequest *request = [NSURLRequest requestWithURL:imageURL];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error){
UIImage *image = [UIImage imageWithData:data];
self.images[indexPath] = image;
completion(image, nil);
} else {
completion(nil, error);
}
}];
}
現在,我們先檢查中的cellForRowAtIndexPath緩存中的圖像修復多個請求的問題。
UIImage *image = self.images[indexPath];
if (image) {
[cell.CellImg setBackgroundImage:image forState:UIControlStateNormal];
} else {
// this is a good place for a placeholder image if you want one
[cell.CellImg setBackgroundImage:nil forState:UIControlStateNormal];
// presuming that 'img' is a string from your mode
[self imageWithPath:img completion:^(UIImage *image, NSError *error) {
// the image is ready, but don't assign it to the cell's subview
// just reload here, so we get the right cell for the indexPath
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
}
還要注意不在完成塊做了什麼......我們被不是指電池固定單元複用。相反,知道圖像現在被緩存,我們重新加載indexPath。
返回圖片大小:大多數應用程序喜歡看到表格視圖單元格與可變高度子視圖一起變得更高或更短。如果是這樣的話,那麼你就不應該在該子視圖上放置高度限制。相反,將其頂部和底部邊緣限制在單元格的內容視圖中(或將其包含在一系列子視圖中,這些子視圖互相約束頂部和底部,幷包含頂部和底部的子視圖頂部和底部的子視圖)。然後(在iOS 5以上,我認爲),這將讓你的細胞與子視圖約束鏈改變HIGHT ...
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = // your best guess at the average height here
我確實在那裏有一個NSCache,只是沒有顯示它,因爲我不認爲這是錯誤背後的原因。 – user2760706