I’ve assortment view with UICollectionViewCompositionalLayout
. Inside my assortment I’ve objects with photos. Once I launch my app I see assortment view. And after I begin scrolling I’ve a number of freezes. However after I scrolled the all assortment, the freezes disappear. I feel that freezes are disappearing after full assortment scroll as a result of the pictures are already loaded. However how can I repair the issue in order that after launching the app and scrolling the gathering for the primary time, it doesn’t freeze?
Video to breed the issue:
https://drive.google.com/file/d/145Bl2Oc3UHgwpJQZjG38YNVOZyWz7euM/view?usp=share_link
There’s quite a lot of code within the app, so I posted the challenge on GitHub:
https://github.com/user234567890354678/carousel
Important code:
assortment view cell
class CVCell: UICollectionViewCell, SelfConfiguringCell {
func configure(with merchandise: Merchandise) {
title.textual content = merchandise.title
textView.backgroundColor = UIColor(merchandise.backgroundColor)
textView.layer.borderColor = UIColor(merchandise.borderColor).cgColor
titleImageView.picture = UIImage(named: merchandise.titleImage)
imageView.picture = UIImage(named: merchandise.picture)
}
}
assortment controller
class CVController: UIViewController, UICollectionViewDelegate {
var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource?
let sections = Bundle.predominant.decode([Section].self, from: "img1.json")
func createDataSource() {
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, merchandise in
swap self.sections[indexPath.section].identifier {
case "carouselCell":
let cell = self.configure(CarouselCell.self, with: merchandise, for: indexPath)
return cell
default: return self.configure(CarouselCell.self, with: merchandise, for: indexPath)
}
}
}
func configure(_ cellType: T.Kind, with merchandise: Merchandise, for indexPath: IndexPath) -> T {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellType.reuseIdentifier, for: indexPath) as? T else { fatalError("(cellType)") }
cell.configure(with: merchandise)
return cell
}
func reloadData() {
var snapshot = NSDiffableDataSourceSnapshot()
snapshot.appendSections(sections)
for part in sections { snapshot.appendItems(part.merchandise, toSection: part) }
dataSource?.apply(snapshot)
}
func setupCollectionView() {
collectionView = UICollectionView(body: view.bounds, collectionViewLayout: createCompositionalLayout())
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
collectionView.isScrollEnabled = false
collectionView.delegate = self
collectionView.contentInsetAdjustmentBehavior = .by no means
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 merchandise = 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 part = NSCollectionLayoutSection(group: group)
part.contentInsets = NSDirectionalEdgeInsets(
prime: (layoutEnvironment.container.contentSize.peak/2) - (groupWidth/2),
main: 0,
backside: 0,
trailing: 0)
part.interGroupSpacing = 64
part.orthogonalScrollingBehavior = .groupPagingCentered
part.contentInsetsReference = .none
part.visibleItemsInvalidationHandler = { (objects, offset, setting) in
objects.forEach { merchandise in
let distanceFromCenter = abs((merchandise.body.midX - offset.x) - setting.container.contentSize.width / 2.0)
let minScale: CGFloat = 0.7
let maxScale: CGFloat = 1.1
let scale = max(maxScale - (distanceFromCenter / setting.container.contentSize.width), minScale)
merchandise.remodel = CGAffineTransform(scaleX: scale, y: scale)
}
}
return part
}
}
func reloadItem(indexPath: IndexPath) {
guard let needReloadItem = dataSource!.itemIdentifier(for: indexPath) else { return }
var snapshot = NSDiffableDataSourceSnapshot()
snapshot.appendSections(sections)
for part in sections { snapshot.appendItems(part.merchandise, toSection: part) }
dataSource?.apply(snapshot)
snapshot.reloadItems([needReloadItem])
dataSource?.apply(snapshot, animatingDifferences: false)
}
}