I often get this issue as a result of requesting that a collection view (or one of its parents) be laid out before it is actually part of the app's view hierarchy. What basically happens is this: lacking a UIWindow
to determine the size of the new view controller's view, the system assigns an arbitrary width of 50 points to the collection's cells. This is often too small to contain its subviews, leading to the clash of constraints.
For example, if I call layoutIfNeeded
during viewDidLoad
then the view controller's view is still floating around without a parent and does not know how big it is. Besides, it would be unnecessary to perform layout at this point since the layout will be invalidated and recalculated when it is added to the hierarchy anyway.
Now, one could get around this as some have suggested by making some constraints optional but with very high priorities. This can be a useful general strategy, but in this case it likely is not. For example, if the content of the cell is inset from the sides of the cell by a certain amount, it's only likely to work if the constraint between the content and the cell's contentView
is not at the required priority. This will make the size of the cell ambiguous, and will throw a different warning.
Messing with constraint priorities without knowing exactly what you're doing can also lead to unforeseen issues, especially when two constraints in the same axis have the same priority and parent. A common issue with stack views is when its children all have the same priority in its primary axis so it can't tell which one to shrink or expand when it cannot be its preferred size.
The best solution in my opinion is to try and avoid laying out the view before it is added to its parent. Add a Constraint breakpoint and run the app. Note the method in which the app stops for the warning; it will probably be on a call to layoutIfNeeded
. Now, replace that with the following:
if view.superview != nil {
view.layoutIfNeeded()
}
This may be all that you need to do. If you still experience this problem then it may be that the collection view's cells are too small, either due to a simple size miscalculation, a problem in its layout object's code, or that the cell's constraints force it to be a specific size that is not the same as the one it is being given by the layout.