2016-02-01 5 views
2

У меня есть UICollectionView, где есть изображение в каждой ячейке. Это изображение загружается URL-адресом. Но когда ячейка прокручивается вне поля зрения, она показывает изображение другой ячейки за секунду, прежде чем загрузка снова будет собственной. Я не знаю, почему это происходит.UICollectionView повторяющаяся ячейка

Вот мой код:

Мой расширение UIImageView для загрузки из URL:

extension UIImageView { 
    public func imageFromUrl(urlString: String) { 

     Alamofire.request(.GET, urlString).responseJSON{ 
      response in 

      if let tilbudimage = UIImage(data: response.data!){ 
       self.image = tilbudimage 

      } 

     } 
    } 
} 

UICollectionView:

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { 
     return 1 
    } 

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

     print(DealArr.count) 

     return DealArr.count 
    } 

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

     let cell = collectionView.dequeueReusableCellWithReuseIdentifier("DealCell", forIndexPath: indexPath) as! DealCell 

     let deal = self.DealArr[indexPath.row] 

     cell.backgroundColor = UIColor.whiteColor() 

     cell.DealImage.imageFromUrl(deal["image"].string!) 
     cell.DealLabel.text = deal["title"].string! + ", " + String(deal["price"].int!) + "kr." 
     cell.DealDescription.text = deal["description"].string! 
     cellarr.append(cell) 



     return cell 




    } 


    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 
     return CGSizeMake(collectionView.frame.width, 450) 
    } 


    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets { 
     return UIEdgeInsetsMake(0, 0, 0, 0) 
    } 

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat { 
     return 0.0 
    } 

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat { 
     return 1.0 
    } 

ответ

2

Вы не убирая изображение при отображении ячейки , Ячейки повторно используются после их удаления с экрана, поэтому перед отображением вам нужно убедиться, что вы очищаете любые данные, которые не должны переноситься. Обычно это обрабатывается путем установки любых данных в новые значения. В случае вашего изображения вместо немедленной установки нового изображения он отправляет асинхронную задачу для извлечения изображения, а затем показывает это изображение в ячейке. Таким образом, изображение будет переназначено, но оно будет ждать, пока оно не получит ответ от сервера с новым изображением, прежде чем очистить старое изображение.

Чтобы исправить это, перед загрузкой нового изображения вы должны установить изображение равным нулю.

cell.DealImage.image = nil 
cell.DealImage.imageFromUrl(deal["image"].string!) 

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

extension UIImageView { 
    public func imageFromUrl(urlString: String) { 
     image = nil 
     Alamofire... 

Вы также можете повысить эффективность загрузки, отменив любые ожидающие запроса при повторном использовании ячейки. Есть хороший учебник, который включает в себя это на raywenderlich, если вам интересно: http://www.raywenderlich.com/85080/beginning-alamofire-tutorial

Вы также можете повысить производительность путем кэширования изображений после их загрузки. Для этого вы можете использовать экземпляр NSCache.

let imageCache = NSCache() 

extension UIImageView { 
    public func imageFromUrl(urlString: String) { 
     if let image = imageCache.objectForKey(urlString) as? UIImage { 
      self.image = image 
     } 
     else { 
      Alamofire.request(.GET, urlString).responseJSON{ 
       response in 
       if let tilbudimage = UIImage(data: response.data!){ 
        self.image = tilbudimage 
        imageCache.setObject(tilbudimage, forKey: urlString) 
       } 
      } 
     } 
    } 
} 
+0

Благодарим вас за ответ @esthepiking. Но, установив изображение на ноль перед загрузкой изображения, я вижу белый фон перед отображением изображения (неудивительно, когда я установил изображение в ноль), нет способа, которым он будет загружаться более плавно, например instagram. –

+0

О, вы также можете установить его по умолчанию или загрузить изображение. Это не обязательно должно быть nil, вам просто нужно установить его на что-то, чтобы он не отображал ранее загруженное изображение – esthepiking

+0

ye okay. Но не существует способа, которым я могу предотвратить его загрузку изображения снова, когда он уже загружен в первый раз. Я нахожу, что это раздражает, что каждый раз, когда ячейка выходит из поля зрения, нужно снова делать запрос на изображение, когда оно видимо. В instagram он не ведет себя так. Может ли скорость сервера иметь определенную роль в этом? –

2

Этот номер можно использовать в пользовательском классе UICollectionViewCell.

override func prepareForReuse() { 
    self.imageView.image = nil // or placeholder image 

    super.prepareForReuse() 
} 
Смежные вопросы