I am facing an issue where the shouldInvalidateLayout(forBoundsChange:) method of a UICollectionViewLayout subclass is not getting called on device rotation, but only when the view controller with the collection view is embedded inside of a UINavigationController. If I remove the root view controller from the navigation controller and show it on its own, this method gets called and my layout is able to then correctly invalidate and update for the new device orientation.
Here's a sample project I created to show the issue. The first tab has just the view controller displayed and you can see by rotating the simulator that shouldInvalidateLayout(forBoundsChange:) is called. The second tab has the same view controller embedded in a navigation controller and on rotation you can see in the console that shouldInvalidateLayout(forBoundsChange:) does not get called. The actual project that I'm seeing this occur in uses a slightly more complex subclass of UICollectionViewLayout, but poses the same issue as seen here with a simple subclass of UICollectionViewFlowLayout. Since our project's layout requires slightly more heavy computations, we rely on shouldInvalidateLayout(forBoundsChange:) returning true and invalidating the layout before recalculating all of the layout attributes. Since this is never called, it causes our cells to remain the same width after rotation instead of updating for the new width.
This behavior is very strange and seems undocumented to me from what I have seen. Does anyone have any insights as to why the navigation controller causes this change and how to modify it so that shouldInvalidate is called on rotation?
Some things I've tried (non-exhaustive list):
- Various combinations of hiding and showing the navigation bar/toolbar to see if they have any effect on the bounds of the view on rotation).
- Verifying that the bounds of the collection view change on rotation. They do, and you can see the updated bounds when debugging the view hierarchy in Xcode.
- Creating the interface entirely programmatically and removing the storyboard. The issue still persists.
- Verifying that this issue occurs on different device types. I've tested this on both iPhones with notch/home indicator safe area insets and those without and see the same issue.
- Using a different collection view layout. The issue is present for both UICollectionViewFlowLayout and a custom UICollectionViewLayout subclass.
Some similar issues I've come across/read (again, a non-exhaustive list since I've been at this so long):
- https://gist.github.com/NeilsUltimateLab/21d551126f0f03b11a0154a681a48e71
- https://www.reddit.com/r/iOSProgramming/comments/bd0yh6/what_are_all_the_conditions_that_trigger/
- How to properly rotate viewcontrollers in UINavigationController?
- https://github.com/radianttap/Fields/issues/3
Thanks for any insights in advance!