UICollectionView with optimized smooth scrolling and improved performance.
I expect that you use this when you want to add UICollectionView displaying images to your app.
We can use SDWebImage. Standing on the shoulders of giants.
Our app will appear unresponsive if our code blocks the main thread. We should connect to network and load image and some tasks in background thread.
This sample uses SDWebImage that load image asynchonously.
imageView.sd_setImage(with: url, placeholderImage: placeholder, options: .retryFailed, completed: { img, error, type, url in })
And resize or Add corner raidus or etc in Background.
DispatchQueue.global(qos: .background).async {
imageView.layer.cornerRadius = self.frame.size.width / 2
imageView.clipsToBounds = true
}
We can load ahead images if you use the following delegate method.
func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
※ loaded images will be often shown on the wrong cell because UICollectionViewCell is reused.
So, Use queue (ImageLoadOperation
) to cancel loading images when the cell showing them gets out of screen.
It is easier for the system to calculate UICollectionViewCell size.
Initialization is slow, especially of UIView. We should avoid initializing as possible as we can.
Like this.
guard imageView == nil else { return }
// initialize an imageView
We expect processing reduction.
- Hide vertical/horizantol scroll indicator.
self.collectionView?.showsVerticalScrollIndicator = false
orself.collectionView?.showsHorizontalScrollIndicator = false
- Remove 'contentView' from UICollectionViewCell.
- Avoid gradients, image scaling, and offscreen drawing.
- Set Views as Opaque When Possible.
- If we set Opaque to NO, the drawing system composites the view normally with other content.
- Cache the size of cells if they aren’t always the same.
- Load contents of cells in background.
- Reduce the number of subviews.
- Fix cell size after loading contents before display it.
We don't have to reload data every time you pull to refresh.
if refreshControl.isRefreshing {
refreshControl.endRefreshing()
}
We should make sure to correctly refresh the collection view layout when transitioning to a different Size Class or rotating the device.
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { [weak self] context in
guard let strongSelf = self else { return }
strongSelf.collectionView?.collectionViewLayout.invalidateLayout()
}, completion: nil)
We expect reducing the processing of Self-Sizing Cells if we use fixed size for cells.
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
return layoutAttributes
}
We can make users feel fast if we add a little animation.
It is important that we offer user-interaction for good user experience.
- Cache the size of cells if they aren’t always the same.
- Manage queue of loading data shown on cell
- Compress image file
- Draw images or buttons or view components
- Use the Correct Collection
- Arrays
- Ordered collections. Access to their contents by index.the order matters.
- Apple Document
- Dictionaries
- Unordered collections. Pairs of keys and values. access to their contents by keyed-value.
- fast insertion and deletion operations
- Apple Document
- Sets
- Unordered collections. fast insertion and deletion operations. Quickly lookup.
- Apple Document
- We should use colorWithPatternImage for pattern Images
- We should go with UIColor’s
colorWithPatternImage
when we show a patterned image which will be repeated or tiled to fill the background. - It’s faster to draw and won’t use a lot of memory in this case.
- We should go with UIColor’s