具有出队的UICollectionView查询

时间:2015-02-12 17:11:58

标签: ios swift uicollectionview

我有一个创建网格的UICollectionView。制作网格的每个单元格都有一个UIImage(在IB中创建)。

我正在使用可重复使用的单元来保持请求。 我怎样才能使用这个单元格和UIImage?在它消失之前,有没有将它存储在一个数组中?我创建了一个标签,但如果这有用,我不会这样做?如果我手动创建每个单元格,那么我的控制器中将有大约100个@IBOutlets!这是我的代码显示单元格..

任何想法都会很精彩。我试图在单元格内部获取UIImage,因此我可以隐藏它并在单元格出列之前命名它。

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("LetterCell", forIndexPath: indexPath) as UICollectionViewCell

        cell.tag = indexPath.row
        return cell
    }

1 个答案:

答案 0 :(得分:0)

图像占用了大量的内存。因此,您通常不希望架构要求您一次将所有图像(或更糟糕的是,单元格)保存在内存中。您希望重用您的集合视图单元格,并且您希望以即时方式从持久存储中检索图像(又名,"懒惰"图像加载)。

为了最大限度地减少应用程序的内存占用,因此您的模型通常会包含最少量的信息,例如只是对这些图像的引用(例如文件名)。仅在UI真正需要时才加载图像。

例如,假设图像是设备的Documents文件夹中的文件,那么您可能有一个文件名数组(在下面的示例中称为imageNames),您可能会这样做类似的东西:

var imageNames = [String]()   // this is populated elsewhere, perhaps `viewDidLoad`

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as CustomCell

    let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
    let imageName = imageNames[indexPath.item]
    let path = documentsFolder.stringByAppendingPathComponent(imageName)
    let image = UIImage(contentsOfFile: path)
    cell.imageView.image = image

    return cell
}

如果您真的想要将这些图像保存在内存中(例如,为了更平滑的响应时间),您可以使用NSCache,但请确保此缓存在接收内存压力时自行清空。例如:

var imageCache = ImageCache()

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as CustomCollectionViewCell

    let imageName = imageNames[indexPath.item]
    if let image = imageCache.objectForKey(imageName) as? UIImage {
        cell.imageView.image = image
    } else {
        let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
        let path = documentsFolder.stringByAppendingPathComponent(imageName)
        if let image = UIImage(contentsOfFile: path) {
            imageCache.setObject(image, forKey: imageName)
            cell.imageView.image = image
        }
    }

    return cell
}

其中

class ImageCache : NSCache {

    var observer: NSObjectProtocol!

    override init() {
        super.init()

        // empty queue upon memory pressure

        observer = NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationDidReceiveMemoryWarningNotification, object: nil, queue: NSOperationQueue.mainQueue()) { [unowned self] notification in
            self.removeAllObjects()
        }
    }

    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(observer)
    }
}

还可以考虑其他优化措施。例如,如果这些图像很大,您可以确保重新加载图像视图,并将图像大小调整为最适合集合视图单元格的图像。但希望这能说明在处理UICollectionView中的图像时的一些基本概念。