admin管理员组

文章数量:1124022

I have collection view with UICollectionViewCompositionalLayout. Inside my collection I have items with images. When I launch my app I see collection view. And when I start scrolling I have multiple freezes. But when I scrolled the all collection, the freezes disappear. I think that freezes are disappearing after full collection scroll because the images are already loaded. But how can I fix the problem so that after launching the app and scrolling the collection for the first time, it does not freeze?

Video to reproduce the problem:

There is a lot of code in the app, so I posted the project on GitHub:

Main code:

collection view cell

class CVCell: UICollectionViewCell, SelfConfiguringCell {
    func configure(with item: Item) {
        title.text = item.title
        textView.backgroundColor = UIColor(item.backgroundColor)
        textView.layer.borderColor = UIColor(item.borderColor).cgColor
        titleImageView.image = UIImage(named: item.titleImage)
        imageView.image = UIImage(named: item.image)
    }
}

collection controller

class CVController: UIViewController, UICollectionViewDelegate {
    var collectionView: UICollectionView!
    var dataSource: UICollectionViewDiffableDataSource<Section, Item>?
    let sections = Bundle.main.decode([Section].self, from: "img1.json")

    func createDataSource() {
        dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
            switch self.sections[indexPath.section].identifier {
            case "carouselCell":
                let cell = self.configure(CarouselCell.self, with: item, for: indexPath)
                return cell
            default: return self.configure(CarouselCell.self, with: item, for: indexPath)
            }
        }
    }
    
    func configure<T: SelfConfiguringCell>(_ cellType: T.Type, with item: Item, for indexPath: IndexPath) -> T {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellType.reuseIdentifier, for: indexPath) as? T else { fatalError("\(cellType)") }
        cell.configure(with: item)
        return cell
    }
    
    func reloadData() {
        var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        snapshot.appendSections(sections)
        for section in sections { snapshot.appendItems(section.item, toSection: section) }
        dataSource?.apply(snapshot)
    }
        
    func setupCollectionView() {
        collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createCompositionalLayout())
        collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        collectionView.isScrollEnabled = false
        collectionView.delegate = self
        collectionView.contentInsetAdjustmentBehavior = .never
        view.addSubview(collectionView)
        collectionView.register(CarouselCell.self, forCellWithReuseIdentifier: CarouselCell.reuseIdentifier)
        
        createDataSource()
        reloadData()
    }
    
    func createCompositionalLayout() -> UICollectionViewLayout {
        UICollectionViewCompositionalLayout { (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
            
            let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),   //
                                                  heightDimension: .fractionalHeight(1)) //
            let item = NSCollectionLayoutItem(layoutSize: itemSize)
                        
            let groupWidth = (layoutEnvironment.container.contentSize.width * 1.05)/3
            let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(groupWidth),  //
                                                   heightDimension: .absolute(groupWidth)) //
            let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
                    
            let section = NSCollectionLayoutSection(group: group)
            section.contentInsets = NSDirectionalEdgeInsets(
                top: (layoutEnvironment.container.contentSize.height/2) - (groupWidth/2),
                leading: 0,
                bottom: 0,
                trailing: 0)
            section.interGroupSpacing = 64
            section.orthogonalScrollingBehavior = .groupPagingCentered
            section.contentInsetsReference = .none
            section.visibleItemsInvalidationHandler = { (items, offset, environment) in
                
                items.forEach { item in
                    let distanceFromCenter = abs((item.frame.midX - offset.x) - environment.container.contentSize.width / 2.0)
                    let minScale: CGFloat = 0.7
                    let maxScale: CGFloat = 1.1
                    let scale = max(maxScale - (distanceFromCenter / environment.container.contentSize.width), minScale)
                    item.transform = CGAffineTransform(scaleX: scale, y: scale)
                }
            }
            
            return section
        }
    }
    
    func reloadItem(indexPath: IndexPath) {
        guard let needReloadItem = dataSource!.itemIdentifier(for: indexPath) else { return }
        var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        snapshot.appendSections(sections)
        for section in sections { snapshot.appendItems(section.item, toSection: section) }
        dataSource?.apply(snapshot)
        snapshot.reloadItems([needReloadItem])
        dataSource?.apply(snapshot, animatingDifferences: false)
    }

}

本文标签: iosMultiple freezes in collection viewStack Overflow