UICollectionView FlowLayout in iOS 10 (only)

I have a problem in iOS 10 (only) with my UICollectionView. My VC has a UICollectionView about 1/3 down from the top. The UICollectionView shows two rows of buttons in six columns. The layout works perfect in iOS 11. But in iOS 10 only one row of buttons show. I've inspected the frame that I am assigning to the UICollectionView and, of course, it's the same in both iOS 10 and iOS 11. There's exactly enough space to fit the two rows. The problem happens in both the simulator and device. I'm using Xcode 9.4.1 and Swift 4.1.

Here's the method that prepares the layout.


private var theLayout: UICollectionViewFlowLayout {
    return (buttonsView.collectionViewLayout as? UICollectionViewFlowLayout)!
  }
func prepareLayout(for frame: CGRect, and numberOfColumns: Int, animated: Bool = false) {
    let size = CGSize(width: frame.size.width / (CGFloat(6), height: frame.size.height / CGFloat(2))

    // Continue only if a change is detected.
    guard buttonsView.frame != frame, theLayout.itemSize != size  else { return }

    // Closure to be run with animation or no animation.
    let updateLayout = {
      self.theLayout.sectionInset = .zero
      self.theLayout.minimumInteritemSpacing = 0
      self.theLayout.minimumLineSpacing = 0
      self.theLayout.itemSize = size // CGSize(width: size.width, height: size.height)
      self.buttonsView.frame = frame
     
      self.theLayout.invalidateLayout()
    }
   
    animated ? UIView.standardAnimations { updateLayout() } : updateLayout()
  }



The UICollectionView is initialized like this:


    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.itemSize = CGSize(width: 70, height: 20)
    buttonsView = UICollectionView(frame: .zero, collectionViewLayout: layout)



According to the AppStore, 14% of devices are still using iOS 10!


I even tried using UICollectionViewDelegateFlowLayout which shouldn't be necessary because all my itms are the same size and I have the same problem.


Anybody know what's going on?

It is difficult to understand why it changes from IOS 10 to IOS 11.

What I've seen in other cases, is that the sequence of system call may have changed, leading to a different behavior.


So, I'm just guessing here,.


- Have you checked that you pass the guard statement ? Likely yes, otherwise nothing would draw

   guard buttonsView.frame != frame, theLayout.itemSize != size  else { return }
   print("I passed guard", frame)


- What is the frame you pass to prepareLayout ?


Could you try to reduce the size a bit :


    let size = CGSize(width: frame.size.width / (CGFloat(6) - CGFloat(4), height: frame.size.height / CGFloat(2) - CGFloat(4))

Yes, I've tried all that. I've even commented out the guard as it's only there to prevent unnecesary updates.


I reduced the height of the itemSize because my issue appear to be height related; meaning, my columns are fine its the number of rows that isn't correct which should be determined by the height.


For an iPad, frame is:

▿ (0.0, 284.0, 768.0, 132.142857142857)

▿ origin : (0.0, 284.0)

- x : 0.0

- y : 284.0

▿ size : (768.0, 132.142857142857)

- width : 768.0

- height : 132.142857142857


and itemSize:

▿ (124.0, 62.0714285714286)

- width : 124.0

- height : 62.0714285714286


All the spacing and inset are = 0.0.


Open to suggestions.

UICollectionView FlowLayout in iOS 10 (only)
 
 
Q