1
votes

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)
    }
}

2

2 Answers

0
votes

Do you have an UIImageView in your cell? That's probably why you're getting 1081.6666666666667 for the content size.

You probably don't want self-sizing cells, so turn off "Estimate Size" in the storyboard. Otherwise, your collection view won't read what's inside sizeForItemAt.

turn estimate size off

0
votes

Can you show your UICollectionView`s init func,i guess you did not set the UICollectionView delegate to self,and the layout itemsize height is larger than 90