照片框架和可重用的 UICollectionViewCell

Posted

技术标签:

【中文标题】照片框架和可重用的 UICollectionViewCell【英文标题】:Photos framework and reusable UICollectionViewCell 【发布时间】:2016-01-29 16:03:48 【问题描述】:

我有一个UICollectionView 来显示带有Photos 框架的设备相册中的照片。照片显示正确,但如果我快速滚动(比如当您在屏幕顶部粘贴以转到 collectionView 的顶部时),我有一些不在好的 indexPath 上的照片。我只需滚动一点,将坏照片从屏幕上移出,然后一切恢复原状。

我在prepareForReuse 期间通过取消当前请求来清理单元格。

我推测是PHImageManager的异步请求有问题,但不知道如何避免这个问题。

这里有一些代码:

视图控制器

extension AlbumDetailViewController : UICollectionViewDataSource 
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int 
        return 1
    

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return photoList.count
    

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

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

        cell.setImage(photoList.objectAtIndex(indexPath.row) as! PHAsset)

        return cell
    

自定义 CollectionViewCell

class PhotoCollectionCell: UICollectionViewCell 

    @IBOutlet weak var imageView: UIImageView!

    var requestId: PHImageRequestID!
    let manager = PHImageManager.defaultManager()

    override func awakeFromNib() 
        super.awakeFromNib()
        // Initialization code
    

    override func prepareForReuse() 
        self.imageView.image = nil

        manager.cancelImageRequest(self.requestId)
    

    func setImage(asset: PHAsset) 

        let option = PHImageRequestOptions()

        option.resizeMode = .Fast
        option.deliveryMode = .HighQualityFormat

        self.requestId = manager.requestImageForAsset(asset, targetSize: CGSize(width: self.frame.size.width * UIScreen.mainScreen().scale, height: self.frame.size.height * UIScreen.mainScreen().scale), contentMode: PHImageContentMode.Default, options: option, resultHandler: (result, info)->Void in
            self.imageView.image = result
        )
    

谢谢

【问题讨论】:

【参考方案1】:

在调用requestImageForAsset方法之前,设置cell.tag等于indexPath.item,在回调中获取图片后,检查indexPath.item和cell.tag,如果匹配就这样做 self.imageView.image = 结果。例如

        cell.tag = indexPath.item

        if let asset = assets?[indexPath.item] 

            let option = PHImageRequestOptions()
            option.isSynchronous = false
            option.resizeMode = .exact
            option.isNetworkAccessAllowed = true

            DispatchQueue.global(qos: .userInitiated).async 
                manager.requestImage(for: asset, targetSize: Constant.targetSize, contentMode: .aspectFit, options: option, resultHandler: (result, info)->Void in

                    DispatchQueue.main.async 

                        if cell.tag == indexPath.item 
                            cell.imageView.image = result
                        
                    
                )
            
        

希望对你有帮助

【讨论】:

以上是关于照片框架和可重用的 UICollectionViewCell的主要内容,如果未能解决你的问题,请参考以下文章

用于在非 SPA 站点上构建可重用组件的 Javascript MVC 框架

我怎样才能使这个对象映射在 Go 中更加干燥和可重用?

初始Mybatis

如何创建可扩展和可维护的前端架构

快速检测从照片库中删除的图像

java框架之MyBatis