2015-03-06 2 views
0

Я думаю, что у меня здесь действительно странная проблема. В некоторых из моих TableViews, когда я загружаю изображения из Parse, ячейки, у которых нет данных, иногда отображаются другие изображения.PFImageView в TableView Cell загружает неправильное изображение

У меня есть мой код, чтобы проверить наличие файла на 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()?

ответ

2

Без использования кэша обходной путь, который я нашел, - это сначала установить файл изображения в cellForRowAtIndexPath на изображение-заполнитель, а затем, если объект изображения был найден на сервере, образ ячеек установлен на новый файл, а затем загружает его в фоновом режиме.

Вот код:

 myCell.profilePic.image = UIImage(named: "placeholder user image") 

     if let file: PFFile = object["profilePicture"] as? PFFile { 
      myCell.profilePic.file = file 
      myCell.profilePic.loadInBackground() 
     } 

Всем спасибо за помощь!

1

Когда вы просматриваете таблицу, ячейки повторно используются. Изображение, показанное ранее в этой ячейке, не очищается. Вы можете использовать метод UITableViewCell prepareForReuse или делегаты UITableView didEndDisplayingCell/willDisplayCell, чтобы аннулировать изображение и отменить загрузку или эту ячейку.

Update

попробовать это:

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    cell.businessPhoto.file.cancel() 
    cell.businessPhoto.image = nil 
} 

Убедитесь, что вместо UITableViewCell здесь используется пользовательский класс клеток

+0

Где бы я их реализовал? Прямо перед тем, как я верну ячейку в 'cellForRowAtIndexPath'? EDIT: Пробовал это, и он просто делает все изображения пустыми. – pbush25

+0

В ответ на обновление: когда я пытаюсь реализовать этот метод с помощью класса 'PFTableViewCell', компилятор говорит, что я не могу переопределить метод из-за несовместимых типов. – pbush25

+0

Да, это одно из возможных решений. Главное - сбросить ячейку перед ее повторным отображением. 'prepareForReuse' /' didEndDisplayingCel'l обычно используются для этого, но ничего не мешает вам сделать это в 'cellForRowAtIndexPath' – f3n1kc

1

Вопрос не показывает код, в котором бизнес установленный на основе 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) 
} 

Обратите внимание, что мы устанавливаем изображение ячейки сразу в любом случае - даже в том случае, когда мы начинаем выборку. Сделанный таким образом, не должно быть необходимости реализовывать hookForReuse или didEndDisplay.

+0

Это, безусловно, правильный ответ, я просто начинающий программист и еще не успел реализовать кеширование. – pbush25

Смежные вопросы