I found that Xcode 26.1.1 (17B100) silently disables UICollectionView self-sizing
configured in Interface Builder, depending on the minimum deployment target. I've fixed this issue in my project by explicitly setting the estimatedItemSize to UICollectionViewFlowLayout.automaticSize, but I was wondering whether this is intended behavior, or am I missing something?
When a XIB contains a UICollectionViewFlowLayout with Estimate Size: Automatic
(automaticEstimatedItemSize="YES" in the document source):
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal"
automaticEstimatedItemSize="YES" minimumLineSpacing="6" minimumInteritemSpacing="6">
<size key="itemSize" width="128" height="32"/>
</collectionViewFlowLayout>
ibtool drops the estimated-size key from the compiled nib if
IPHONEOS_DEPLOYMENT_TARGET is 17.0 or later. It can be confirmed by compiling the
same XIB at two deployment targets:
$ ibtool --target-device iphone --minimum-deployment-target 16.0 --compile out16.nib View.xib
$ strings out16.nib | grep -i estimat
estimatedItemSize # present
$ ibtool --target-device iphone --minimum-deployment-target 17.0 --compile out17.nib View.xib
$ strings out17.nib | grep -i estimat
# (nothing - key is gone)
At runtime the flow layout decodes estimatedItemSize = .zero, so self-sizing is
silently disabled and every cell is laid out at the placeholder Cell Size (128x32 above),
regardless of its content:
decoded estimatedItemSize = (0.0, 0.0), itemSize = (128.0, 32.0) // target 17.0
decoded estimatedItemSize = (1.79e+308, 1.79e+308) // target 16.0, works
This is independent of the runtime OS version — I reproduced it on iOS 18.4 and
iOS 26.1 simulators. The information is simply missing from the compiled nib, and no
build warning or error is emitted. Confusingly, UIKit still calls the cell's
preferredLayoutAttributesFitting(_:), so cells appear to compute correct sizes;
they are just never adopted by the layout, which makes this quite hard to debug.
Workaround — set it in code after the nib loads (the XIB cannot be fixed at the source level because the attribute is dropped at compile time):
(collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.estimatedItemSize =
UICollectionViewFlowLayout.automaticSize
I attached minimal reproduction project (toggle IPHONEOS_DEPLOYMENT_TARGET between 16.0 and
17.0 to see both behaviors) to the feedback filed as FB23526517