首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UICollectionViewDiffableDataSource cellProvider比预期更频繁地打电话

UICollectionViewDiffableDataSource cellProvider比预期更频繁地打电话
EN

Stack Overflow用户
提问于 2020-12-03 18:23:31
回答 1查看 829关注 0票数 6

我正在使用UICollectionViewDiffableDataSource填充我的UICollectionView。在通过REST接收到项目列表后,我创建了一个新的快照,并按如下方式应用:

代码语言:javascript
复制
DispatchQueue.main.async {
   var snapshot = NSDiffableDataSourceSnapshot<RegionSection, DiffableModel>()
   snapshot.appendSections(RegionSection.allCases)
   snapshot.appendItems(self.spotlights, toSection: .Spotlights)
   snapshot.appendItems(self.vendors, toSection: .Vendors)
   self.dataSource?.apply(snapshot, animatingDifferences: animated)
}

在cellProvider中设置单元格时,我会异步地从URL加载图像。我注意到,第一个单元格会疯狂地浏览所有加载的图像,并最终显示出与预期不同的图像。(例如,拟由最后一个单元格显示的图像)。

我决定调查并发现,-- cellProvider闭包被调用的次数是预期的两倍。在调用的前半部分中,collectionView.dequeueReusableCell函数的行为也很奇怪,因为它每次都返回相同的单元,尽管collectionView中没有可以退出队列的单元。

我的cellProvider结束:

代码语言:javascript
复制
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { (collectionView, indexPath, entry) -> UICollectionViewCell? in
    if let spotlight = entry as? Spotlight{
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "spotlightCell", for: indexPath) as! SpotlightCell
        
        cell.nameLabel.text = spotlight.title
        cell.subtitleLabel.text = spotlight.subtitle
        cell.categoryLabel.text = spotlight.type.getDescription().uppercased()
        cell.imageView.loadImage(fromUrl: spotlight.titlePictureUrl)
                    
        return cell
    }else if let vendor = entry as? Vendor{
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "vendorCell", for: indexPath) as! VendorCell
        
        cell.nameLabel.text = vendor.title
        cell.assortmentLabel.text = vendor.assortmentDescription
        cell.imageView.loadImage(fromUrl: vendor.titlePictureUrl ?? vendor.pictureUrls?.first ?? "")
        
        if let distance = vendor.distance{
            cell.distanceLabel.text = (distance/1000) < 1 ? (distance.getReadableString(withDecimalSeparator: ",", andDecimalCount: 0) + "m entfernt") : ((distance/1000).getReadableString(withDecimalSeparator: ",", andDecimalCount: 0) + "km entfernt")
        }
                    
        return cell
    }
    return nil
}

下面是一个示例:

  1. 我创建了一个包含4个供应商条目的快照(为了简单起见,我没有在本例的另一部分中添加任何内容),
  2. cellProvider被调用4次(对于每个indexPath和条目),并且每次退出队列的单元格都是相同的。
  3. cellProvider又被调用了4次(同样,对于每个indexPath和条目),而这一次单元格是不同的。每次调用cellProvider的
  4. ,它试图在我的图像缓存中为URL找到一个图像,如果它找不到一个加载它,则asynchronously.
  5. Since所有调用几乎同时发生,每个图像几乎同时加载两次,第一个单元格一个接着一个地显示图像,直到它启动的4 URLSessions中的最后一个返回。

我无法想象dataSource经常会调用它是cellProvider闭包的行为,我只是不知道为什么会发生这种情况,也无法在这方面的文档中找到任何东西。

我希望有人能向我解释为什么会发生这种情况,如果这是预期的行为,如何使用DiffableDataSource正确设置异步映像加载的单元格。

编辑:为我工作的解决方案是使用绝对,而不是估计我的细胞大小,如@Norb Braun!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-16 09:37:26

将估计大小设置为none为我解决了这个问题。当您需要使用自调整大小的单元格时,此解决方案可能不适用于您,但是如果您的单元格保持相同的大小,不管内容如何,您可以尝试一下。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65131885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档