Here's a fairly basic question about current iOS development, to which I've never found a good answer.
In a (say) vertical UICollectionView
,
Is it possible to have full-width cells, but, allow the dynamic height to be controlled by autolayout?
(If you're new to iOS "dynamic height", meaning the cell has a few, say, text views which could be any length or images which could be different sizes, so ultimately each cell is a totally different height.)
If so how?
This strikes me as perhaps the "most important question in iOS with no really good answer."
You have to add width constraint to CollectionViewCell
Problem
You are looking for automatic height and also want to have full in width , it is not possible to get both in using
UICollectionViewFlowLayoutAutomaticSize
. why you don't takeUITableVIew
instead ofUICollectionView
in which you can just return in theheightForRow
asUITableViewAutomaticDimension
it will be managed automatically . anyways you want to do usingUICollectionView
so below is the solution for you.Solution
1. : If you have only
UILabel
inColllectionViewCell
than set thenumberOfLines=0
and that calculated the expected height ofUIlable
, pass the all three paramters2. : if your
ColllectionViewCell
contains onlyUIImageView
and if it's is supposed to be dynamic in Height than you need to get the height ofUIImage
(yourUIImageView
must haveAspectRatio
constraints )3. if it contains both than calculated their height and add them together.
1. Add
UICollectionViewDelegateFlowLayout
delegate in your viewController2. Implement the delegate method
i hope this will help you out .
Per my comment on Eric's answer, my solution is very similar to his, but I had to add a constraint in preferredSizeFor... in order to constrain to the fixed dimension.
This question has a number of duplicates, I answered it in detail here: https://stackoverflow.com/a/47424930/2171044, and provided a working sample app here.
Set
estimatedItemSize
of your flow layout:Define a width constraint in the cell and set it to be equal to superview's width:
Full example: https://gist.github.com/madyanov/246217ad2628ba6a870114131a27c55c
Tested on iOS 11.
You have to inherit the class UICollectionViewDelegateFlowLayout on your collectionViewController. Then add the function:
Using that, you have the width size of the screen width.
And you now have a collectionViewController with rows as a tableViewController.
If you want the size of the height of each cell to be dynamically, perhaps you should create custom cells for each cell you need.
With Swift 4.2 and iOS 12, you can subclass
UICollectionViewFlowLayout
and set itsestimatedItemSize
property toUICollectionViewFlowLayoutAutomaticSize
(this tells the system that you want to deal with autoresizingUICollectionViewCell
s). You'll then have to overridelayoutAttributesForElements(in:)
andlayoutAttributesForItem(at:)
in order to set cells width. Lastly, you'll have to override your cellspreferredLayoutAttributesFitting(_:)
method and compute their compressed fitting height.The following complete code shows how to display multiline
UILabel
inside full-widthUIcollectionViewCell
(constrained byUICollectionView
's safe area andUICollectionViewFlowLayout
's insets):CollectionViewController.swift
FlowLayout.swift
Cell.swift
Here are some alternative implementations for
preferredLayoutAttributesFitting(_:)
:Expected display: