Make UICollectionViewCell's height match its c

2020-05-07 07:04发布

I found the next answer to make UIView's height match its content https://stackoverflow.com/a/39527226/7767664

I tested it, it works fine (if UIView height size in storyboard bigger or smaller than its content then during runtime it autoresize itself to match the content).

But if I use UICollectionViewCell instead of UIView then nothing changes, height of cell is never changed, it always has the hardcoded height we have in storyboard properties:

enter image description here

What else can I do?

Also I have 2 sections in UIControllerView (2 columns). Two cells in one row should have the same size even if their size content is different (something like this implemented in Android natively when using RecyclerView with GridLayoutManager, very easy)

Update

It works with UIView because I set its top constraint to Safe Are'a top

I can't do it with UICollectionViewCell

Update 2

It seems I have some progress with this answer https://stackoverflow.com/a/25896386/7767664

But instead of newFrame.size.width = CGFloat(ceilf(Float(size.width))) I need newFrame.size.height = CGFloat(ceilf(Float(size.height)))

and when we use this solution, don't add any constraints to cell's bottom otherwise it will not work

With this solution I can't really use any margins otherwise some part of becomes invisible at the bottom of cell

I guess it can be solved with this question https://stackoverflow.com/a/31279726/7767664

2条回答
啃猪蹄的小仙女
2楼-- · 2020-05-07 07:35

I solved my issue thanks to https://stackoverflow.com/a/25896386/7767664 and https://stackoverflow.com/a/31279726/7767664

I decided to put one UIView with all needed child views inside it to UICollecitonViewCell

I set UIView trailing, leading, top to ICollecitonViewCell but I didn't set bottom to cell view (you should use the latest child view inside UIView and connect their bottoms, not with the cell view)

Then I added reference of UIView to my custom cell class and I use its height for cell's height:

public class MyCustomItemCell: UICollectionViewCell {

    // other child views references ...

    @IBOutlet weak var wrapperView: UIView! // view which contains your other views

    //forces the system to do one layout pass
    var isHeightCalculated: Bool = false

    override public func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
        //Exhibit A - We need to cache our calculation to prevent a crash.
        if !isHeightCalculated {
            setNeedsLayout()
            layoutIfNeeded()
            var newFrame = layoutAttributes.frame
            newFrame.size.height = wrapperView.frame.height // use height of our UIView
            layoutAttributes.frame = newFrame
            isHeightCalculated = true
        }
        return layoutAttributes
    }
}
查看更多
ら.Afraid
3楼-- · 2020-05-07 07:36

You can try with this function called inside you collectionView Extension or inside your native collectionViewController class:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
    {
        //return something like the size. I write you an example how to use it.
        // You can easily change the value according to your stuff contents height.

        return CGSize(width: collectionView.frame.size.width/3, height: 100)
    }

查看更多
登录 后发表回答