I have a horizontally scrolling UICollectionView
using the flow layout that has its delegate and datasource set. It has a height of 50 and is pinned to my view using autolayout. Unfortunately, it never displays and always gives the following error:
2020-10-09 21:30:08.687110+0100 MyApp[8679:1601772] The behavior of the UICollectionViewFlowLayout is not defined because: 2020-10-09 21:30:08.687428+0100 MyApp[8679:1601772] the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values. 2020-10-09 21:30:08.687743+0100 MyApp[8679:1601772] Please check the values returned by the delegate. 2020-10-09 21:30:08.688641+0100 MyApp[8679:1601772] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x105dc6350>, and it is attached to <UICollectionView: 0x10611d000; frame = (0 0; 375 90); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x28372ccf0>; layer = <CALayer: 0x2839465c0>; contentOffset: {0, 0}; contentSize: {1081.6666666666667, 90}; adjustedContentInset: {0, 0, 0, 0}> collection view layout: <UICollectionViewFlowLayout: 0x105dc6350>. 2020-10-09 21:30:08.688943+0100 MyApp[8679:1601772] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
I've noticed that it is saying the contentSize is {1081.6666666666667, 90}
but it actually only calls the numberOfSections
and numberOfItemsInSection
delegate methods. The others aren't called, and neither is the UICollectionViewDelegateFlowLayout
sizing method. Why is this and how is it getting a contentSize without actually calling the datasource/delegate methods? It makes no difference if I set the autolayout height from 50 to 90.
My collectionView is set up in the storyboard. I have registered my cell and set the estimated flow layout size like so:
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(
UINib(nibName: "VideoClipCell", bundle: nil),
forCellWithReuseIdentifier: "VideoClipCell"
)
if let flowLayout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.estimatedItemSize = CGSize(width: 30, height: 50)
}
}
These are the datasource/flow delegate methods:
extension EditingViewController : UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: "VideoClipCell", for: indexPath) as? VideoClipCell else {
return UICollectionViewCell()
}
return cell
}
}
extension EditingViewController: UICollectionViewDelegateFlowLayout {
func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 50)
}
}