Câu hỏi này được vài tuổi, nhưng có lẽ câu trả lời này có thể hữu ích cho người khác có vấn đề tương tự, như tôi trước đây để tìm ra giải pháp đúng.
Vì hình ảnh được tải không đồng bộ, nếu chúng tôi không cung cấp chiều cao cố định cho UIIMageView , chúng tôi buộc phải cập nhật ô khi tải xuống hoàn tất. Điều này vì việc cập nhật ô (tức là tính toán lại tính toán tự động) được thực hiện tự động chỉ sau phương thức cellForRowAt
, được gọi khi lần đầu tiên ô được hiển thị hoặc khi bảng được cuộn để hiển thị các ô khác. Trong cả hai trường hợp, có lẽ các hình ảnh chưa được tải xuống theo phương thức af_setImage()
, do đó không có gì ngoài trình giữ chỗ sẽ được hiển thị vì các kích thước của chúng chưa được xác định cho thời điểm này.
Để bắt buộc cập nhật ô, chúng tôi cần sử dụng phương pháp beginUpdates()
và endUpdates()
, đặt chúng bên trong trình xử lý hoàn thành .af_setImage()
. Bằng cách này, mỗi lần tải xuống hoàn tất, ô sẽ được cập nhật.
Tuy nhiên, để tránh một vòng lặp, trước khi gọi beginUpdates()
/endUpdates()
chúng ta phải kiểm tra xem chúng tôi đã cập nhật các tế bào trước, bởi vì bằng cách gọi phương pháp này, phương pháp cellForRowAt
được gọi là một lần nữa và do đó af_setImage()
và nó hoàn thành đóng cửa với beginUpdates()
/endUpdates()
bên trong nó).
Điều này có nghĩa là chúng tôi chỉ cập nhật ô khi quá trình tải xuống hoàn tất và không phải khi hình ảnh đã được đổi thành tiền mặt (bởi vì, nếu được đổi thành tiền mặt, có nghĩa là chúng tôi đã cập nhật ô).Điều này có thể được thực hiện bằng cách kiểm tra đáp ứng của trình xử lý hoàn thành: nếu nó không phải là nil
, hình ảnh chỉ bị downoladed, nếu nó là nil
, hình ảnh đã được đổi thành tiền mặt.
Là một bên có lợi cho chiều cao di động sẽ được điều chỉnh Automagically (nhớ để đặt tableView.estimatedRowHeight = 400
và tableView.rowHeight = UITableViewAutomaticDimension
trong phương pháp viewDidLoad()
của bạn)
Cuối cùng, ở đây nó là mã:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue your cell
let cell = self.tableView.dequeueReusableCell(withIdentifier: "YourCustomCellIdentifier") as! YourCustomTableViewCell
// get picture url from the data array
let pictureUrl = self.yourCellsData[indexPath.row].pictureUrl
// async download
cell.pictureView.af_setImage(
withURL: URL(string: pictureUrl)!,
placeholderImage: UIImage(named: "YourPlaceholder.png"),
filter: nil,
imageTransition: UIImageView.ImageTransition.crossDissolve(0.5),
runImageTransitionIfCached: false) {
// Completion closure
response in
// Check if the image isn't already cached
if response.response != nil {
// Force the cell update
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
}
return cell
}
Đó là tất cả các folks! ;-)
Dường như kích thước cell.imageView tương ứng, tùy thuộc vào việc có hình ảnh hay không. Nếu không có hình ảnh, nó co lại khung của nó để không có không gian. Vì vậy, khi bạn không sử dụng một trình giữ chỗ, nó nghĩ rằng không có hình ảnh, do đó co lại chính nó. Sau đó, khi hình ảnh đến không đồng bộ, khung hình đã bị thu hẹp, do đó không có nơi nào để đặt hình ảnh. – Harris