setImageWithURLRequest AFNetworking устанавливает изображение в неправильной ячейке после прокрутки (iOS, Swift)

Я использую таблицу с dequeueReusableCellWithIdentifier и afnetworking+uiimageview. В некоторых из моих ячеек есть изображения, в некоторых нет. Если я прокручиваю свою таблицу до того, как изображение загрузится, блок успеха поместит изображение в повторно используемую неправильную ячейку. Например, изображение было в ячейке № 2, но после прокрутки оно появляется в ячейке № 8, потому что № 8 в тот момент был на второй позиции. Можно ли использовать setImageWithURLRequest вместе с dequeueReusableCellWithIdentifier?

Мой код:

    let cell = tableView.dequeueReusableCellWithIdentifier("simpleCell", forIndexPath: indexPath) as UITableViewCell!
    cell.textLabel.text = fields[indexPath.row]["name"] as String
    cell.imageView.image = nil
    if let image = fields[indexPath.row]["image"] as? String {
        if (image != "") {
            let image_url = NSURL(string: image)
            let url_request = NSURLRequest(URL: image_url)
            let placeholder = UIImage(named: "no_photo")
            cell.imageView.setImageWithURLRequest(url_request, placeholderImage: placeholder, success: { [weak cell] (request:NSURLRequest!,response:NSHTTPURLResponse!, image:UIImage!) -> Void in
                if let cell_for_image = cell {
                    cell_for_image.imageView.image = image
                    cell_for_image.setNeedsLayout()
                }
            }, failure: { [weak cell]
               (request:NSURLRequest!,response:NSHTTPURLResponse!, error:NSError!) -> Void in
                if let cell_for_image = cell {
                    cell_for_image.imageView.image = nil
                    cell_for_image.setNeedsLayout()
                }
            })
        }
    }
    return cell

извините, если мой вопрос дублирует другой. Нашел много похожих вопросов, но решения не нашел. попробовал добавить перезагрузку

tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)

в мой блок успеха, но это не помогает.

ОБНОВЛЕНИЕ: я также заметил, что у меня нет этой проблемы в случаях, когда все мои ячейки имеют изображения. Если я правильно понял, причина в следующем: AFNetworking прерывает предыдущий запрос для той же ячейки при попытке запросить новое изображение. Но если у меня нет изображения в ячейке, оно не прервется. Как я могу сделать это вручную?


person John Kakon    schedule 29.08.2014    source источник


Ответы (2)


Когда ячейка повторно используется табличным представлением, загрузка изображения все еще выполняется в фоновом режиме. По завершении cell указывает на повторно используемую ячейку с другим содержимым.

У вас есть два варианта:

  1. Вызовите cancelImageRequestOperation в представлении изображения после cell.imageView.image = nil
  2. В обработчике завершения не ссылайтесь на cell; вместо этого используйте свою модель данных, чтобы запросить правильную ячейку из табличного представления.
person Aaron Brager    schedule 29.08.2014
comment
1. Именно то, что мне нужно! Благодарю вас! 2. Что вы имеете в виду? Должен ли я снова создать его с помощью dequeueReusableCellWithIdentifier? - person John Kakon; 29.08.2014
comment
Нет, просто определите путь к индексу, а затем вызовите cellForRowAtIndexPath: в табличном представлении (не в контроллере представления) - person Aaron Brager; 29.08.2014

Проверьте, видна ли ячейка

let visibleCells = tableView.visibleCells as NSArray
cell.imageView.setImageWithURLRequest(url_request, placeholderImage: placeholder, success: { [weak cell] (request:NSURLRequest!,response:NSHTTPURLResponse!, image:UIImage!) -> Void in
                if let cell_for_image = cell {
                    if(visibleCells.containsObject(cell)) {
                      cell_for_image.imageView.image = image
                      cell_for_image.setNeedsLayout()
                    }

                }
            }, failure: { [weak cell]
               (request:NSURLRequest!,response:NSHTTPURLResponse!, error:NSError!) -> Void in
                if let cell_for_image = cell {
                    cell_for_image.imageView.image = nil
                    cell_for_image.setNeedsLayout()
                }
            })
person Thiago Magalhaes    schedule 29.08.2014
comment
Привет. Спасибо за ваш ответ, но я думаю, что ячейка всегда видна, потому что я повторно использую ячейки. Это всегда один и тот же объект ячейки, но с разным содержимым. Не так ли? - person John Kakon; 29.08.2014
comment
Затем вы должны проверить что-то уникальное в этой ячейке. Например, какой-то пользовательский идентификатор для каждого из них. Какое-то имущество... - person Thiago Magalhaes; 29.08.2014