How to Adjust Height of Uicollectionview to Be the Height of the Content Size of the Uicollectionview

How to adjust height of UICollectionView to be the height of the content size of the UICollectionView?

I would suggest the following:

  1. Add a height constraint to your collection view.
  2. Set its priority to 999.
  3. Set its constant to any value that makes it reasonably visible on the storyboard.
  4. Change the bottom equal constraint of the collection view to greater or equal.
  5. Connect the height constraint to an outlet.
  6. Every time you reload the data on the collection view do the following:

You may also want to consider the Inset of the collection view by adding it to the content size.

Code Sample:

CGFloat height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
heightConstraint.constant = height
self.view.setNeedsLayout() Or self.view.layoutIfNeeded()

Explanation: Extra, You don't have to read if you understand it. obviously!!

The UI will try to reflect all the constraints no matter what are their priorities. Since there is a height constraint with lower priority of (999), and a bottom constraint of type greater or equal. whenever, the height constraint constant is set to a value less than the parent view height the collection view will be equal to the given height, achieving both constraints.

But, when the height constraint constant set to a value more than the parent view height both constraints can't be achieved. Therefore, only the constraint with the higher priority will be achieved which is the greater or equal bottom constraint.

The following is just a guess from an experience. So, it achieves one constrant. But, it also tries to make the error in the resulted UI for the other un-achieved lower priority constraint as lowest as possible. Therefore, the collection view height will be equal to the parent view size.

Constrain UICollectionView height to match height of contents

A better location to update the constraint is viewDidLayoutSubviews, which gets called after every re-layout (orientation changes, size changes, etc). Also, it's more reliable to ask the collection view layout for the content size:

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

// Update placeholder constraint
self.heightConstraint.constant = self.collection.collectionViewLayout.collectionViewContentSize.height
}

UICollectionView autosize height

I solved this eventually by fixing all Auto Layout issues, fixing the height of the collection view using a constraint. Then, whenever I know the content has changed I update the value of the constraint using the value collectionView.contentSize.height:

self.verticalLayoutConstraint.constant = self.collectionView.contentSize.height;

Then the collection view is resized properly and it behaves nicely within the overall scrollview. I have updated the GitHub test project with my changes.

To me, doing this by updating the constraint manually instead of being able to tell iOS: "make the frame height of the collection view as large as needed" does not feel right to me, but it's the best I have come up with so far. Please post a better answer if you have one.

How to dynamically change the height of UICollectionView to adapt to content size

At what point are you trying to read the collectionViewContentSize value?

If you are doing that right after a reloadData() call - that might not give you accurate results because these calls are deferred to be executed at some point on main thread. The content size won't change immediately after doing the reloadData() call.

Try following :

  1. Declare a variable inside the class like this.
private var contentSizeObservation: NSKeyValueObservation?

  1. Start observing contentSize changes.
contentSizeObservation = deadlinesCollectionView.observe(\.contentSize, options: .new, changeHandler: { [weak self] (cv, _) in
guard let self = self else { return }
self.deadlineCollectionViewHeight.constant = cv.collectionViewLayout.collectionViewContentSize.height
})

  1. Do NOT Forget to clean this up in deinit call -
deinit {
contentSizeObservation?.invalidate()
}

This approach will make sure that your collectionView is always as big in height as it's content.

How to determine height of UICollectionView with FlowLayout

Whoa! For some reason, after hours of research, I now found a pretty easy answer to my question: I was completely searching in the wrong place, digging through all the documentation I could find on UICollectionView.

The simple and easy solution lies in the underlying layout: Just call collectionViewContentSize on your myCollectionView.collectionViewLayout property and you get the height and width of the content as CGSize. It's as easy as that.

Size height for item collection view

create Constraint CollectionViewHeight.

@IBOutlet weak var collectionViewHeight: NSLayoutConstraint!

and then, try this Code.

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let height = collectionView.collectionViewLayout.collectionViewContentSize.height
collectionViewHeight.constant = height
self.view.layoutIfNeeded()
}

How to set UICollectionViewCell Width and Height programmatically

Use this method to set custom cell height width.

Make sure to add this protocols

UICollectionViewDelegate

UICollectionViewDataSource

UICollectionViewDelegateFlowLayout

If you are using swift 5 or xcode 11 and later you need to set Estimate Size to none using storyboard in order to make it work properly. If you will not set that than below code will not work as expected.

Sample Image

Swift 4 or Later

extension YourViewController: UICollectionViewDelegate {
//Write Delegate Code Here
}

extension YourViewController: UICollectionViewDataSource {
//Write DataSource Code Here
}

extension YourViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: screenWidth, height: screenWidth)
}
}

Objective-C

@interface YourViewController : UIViewController

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(CGRectGetWidth(collectionView.frame), (CGRectGetHeight(collectionView.frame)));
}


Related Topics



Leave a reply



Submit