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 здесь вы используете свой собственный класс ячейки

Другие вопросы по тегам