PFImageView в ячейке TableView загружает неправильное изображение
Я думаю, что у меня действительно странная проблема здесь. В некоторых из моих TableViews, когда я загружаю изображения из Parse, ячейки, в которых нет данных, иногда отображают другие изображения.
У меня есть код, чтобы проверить наличие файла в Parse, и, если изображение есть, PFImageView
загружает изображение в фоновом режиме для каждой ячейки.
Но, если в базе данных нет изображения, PFImageView
предполагается использовать локальное изображение, которое является заполнителем. Однако часто в моем PFTableView
, ячейки без данных изображения принимают изображения от других ячеек. У кого-нибудь есть идеи почему? Или знаете, как исправить?
Вот код:
if business["businessImage"] as? PFFile != nil {
var file: PFFile = business["businessImage"] as PFFile
cell.businessPhoto.file = file
cell.businessPhoto.loadInBackground()
}
else {
cell.businessPhoto.image = UIImage(named: "placeholder user photo")
}
Это потому, что я использую loadInBackground()
вместо loadInBackgroundWithBlock()
?
3 ответа
Без использования кэша, я нашел обходной путь, чтобы сначала установить файл изображения в cellForRowAtIndexPath
для изображения-заполнителя, а затем, если объект изображения был найден на сервере, для изображения ячеек устанавливается новый файл, а затем загружается его в фоновом режиме.
Вот код:
myCell.profilePic.image = UIImage(named: "placeholder user image")
if let file: PFFile = object["profilePicture"] as? PFFile {
myCell.profilePic.file = file
myCell.profilePic.loadInBackground()
}
Спасибо всем за помощь!
Вопрос не показывает код, где бизнес установлен на основе indexPath. Надеюсь, это просто простой поиск в массиве на основе строки.
Одна определенная проблема с размещенным кодом заключается в том, что он не сразу устанавливает cell.businessPhoto.image
в случае, когда вы делаете асинхронную выборку.
Эффект, который вы увидите, состоит в том, что ячейка будет содержать изображение из другой строки (из-за повторного использования), пока происходит выбор правильного изображения. Решение состоит в том, чтобы установить изображение-заполнитель безоговорочно.
Вторая проблема является более необязательной, но почти обязательной: кэширование изображений. Таким образом, вы не продолжаете повторную загрузку, когда пользователь прокручивает. Это приводит к другой организации в вашем коде cellForRowAtIndexPath:
// this outer conditional is your original code
if (this business has a "businessImage" PFFile) {
// new: check for cached image
if (the image is cached) {
set cell image to the cached image
} else {
// new: always set a placeholder, maybe a special one for fetching
set cell image to a placeholder (one that indicates fetching)
asynch fetch the image, with completion block {
cache the image
set cell image to the image
}
}
} else {
set cell image to a placeholder (one that indicates no image)
}
Обратите внимание, что мы устанавливаем изображение ячейки немедленно в каждом случае - даже в том случае, когда мы запускаем выборку. Для этого не нужно реализовывать хуки prepareForReuse или didEndDisplay.
Когда вы просматриваете таблицу, ячейки используются повторно. Изображение, которое было показано ранее в этой ячейке, не очищается. Вы можете использовать либо метод UITableViewCell prepareForReuse, либо делегаты UITableView didEndDisplayingCell / willDisplayCell, чтобы аннулировать изображение и отменить загрузку или эту ячейку.
Обновить
попробуй это:
func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.businessPhoto.file.cancel()
cell.businessPhoto.image = nil
}
Убедитесь, что вместо UITableViewCell здесь вы используете свой собственный класс ячейки