繁体   English   中英

UICollectionView查询出队

[英]UICollectionView queries with dequeuing

我有一个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
    }

图像占用大量内存。 结果,您通常不希望一种架构要求您一次将所有图像(或更糟糕的是,单元格)保存在内存中。 您希望您的集合视图单元格可以重用,并且您希望以一种及时的方式(也就是“惰性”图像加载)从持久性存储中检索图像。

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

例如,假设图像是设备的“应用程序支持”文件夹中的文件,那么您可能具有文件名数组(在下面的示例中称为imageNames ),并且您可能会执行以下操作:

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CustomCell

    let imageURL = try! FileManager.default
        .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        .appendingPathComponent(imageNames[indexPath.item])

    cell.imageView.image = UIImage(contentsOfFile: imageURL.path)

    return cell
}

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

var imageCache = ImageCache()

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CustomCell

    let imageName = imageNames[indexPath.item]
    if let image = imageCache[imageName] {
        cell.imageView.image = image
    } else {
        let imageURL = try! FileManager.default
            .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            .appendingPathComponent(imageName)
        let image = UIImage(contentsOfFile: imageURL.path)
        imageCache[imageName] = image
        cell.imageView.image = image
    }

    return cell
}

哪里

class ImageCache: NSCache<NSString, UIImage> {

    var observer: NSObjectProtocol?

    override init() {
        super.init()

        // empty queue upon memory pressure

        observer = NotificationCenter.default.addObserver(forName: UIApplication.didReceiveMemoryWarningNotification, object: nil, queue: .main) { [unowned self] notification in
            self.removeAllObjects()
        }
    }

    deinit {
        NotificationCenter.default.removeObserver(observer!)
    }

    subscript(key: String) -> UIImage? {
        get { return object(forKey: key as NSString) }
        set { setValue(newValue, forKey: key) }
    }
}

人们可能还会考虑其他优化。 例如,如果这些图像很大,则可能要确保您正在加载的图像视图中的图像大小已调整为最适合集合视图单元格的大小。 但是希望这可以说明在UICollectionView处理图像时的一些基本概念。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM