UICollectionView重复单元格

时间:2016-02-01 23:15:17

标签: swift uicollectionview xcode7 uicollectionviewcell

我有一个UICollectionView,每个单元格中都有一个图像。这些图像由URL加载。但是当一个单元格滚出视图时,它会再次显示另一个单元格的图像,然后再加载。我不知道为什么会这样。

这是我的代码:

我的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 个答案:

答案 0 :(得分:4)

显示单元格时,您无法清除图像。单元格从屏幕上移除后会重复使用,因此在显示之前,您需要确保清除任何不应被移除的数据。通常,这可以通过将任何数据设置为新值来处理。对于图像,不是立即设置新图像,而是调度异步任务以获取图像,然后在单元格中显示该图像。因此,图像将被重新分配,但它将等到它在清除旧图像之前从服务器接收到具有新图像的响应。

要解决此问题,您应该在加载新图像之前将图像设置为nil。

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)
                }
            }
        }
    }
}

答案 1 :(得分:3)

您可以使用自定义UICollectionViewCell类中的这个。

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

    super.prepareForReuse()
}