0

I have UICollectionView that has dynamic height. It is stored inside CustomUIView.xib

Later that xib view is placed inside UIStackView, which is part of UITableView cell with automatic row height.

Dynamic height doesn't work is such case and I don't see that collection view.

disabling dynamic height makes collection view work fine there but need to scroll to see all content

Also, if I palace that UICollectionView directly into that table view cell - dynamic height work fine. Also if I place that CustomUIView.xib somewhere in simple page with scroll view - collection's view dynamic height works fine.

Is is possible to make at all? If yes - how?

Reloading data, reloading views did help.

EDIT

Here's how I create xib view:

    override init(frame: CGRect) {
    super.init(frame: frame)
    setupView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupView()
}

func setupView() {
    Bundle.main.loadNibNamed("BusyCardView", owner: self, options: nil)
    contentBackgroundView.fixInView(self)
    
    busyCardView.layer.cornerRadius = 10
    
    let selectedActivitiesColumnLayout = FlowLayout(
        minimumInteritemSpacing: 10,
        minimumLineSpacing: 10,
        sectionInset: UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 0)
    )
    
    kidsCollectionView.dataSource = self
    kidsCollectionView.delegate = self
    
    kidsCollectionView.collectionViewLayout = selectedActivitiesColumnLayout
    kidsCollectionView.register(UINib(nibName: "ManageKidsCollectionViewCell", bundle: nil),
                                forCellWithReuseIdentifier: "ManageKidsCollectionViewCell")
}

And here's how I add it to stack view in table view cell:

    func setupBusyCells(date: String, card: Bool) {
    dateLabel.text = date

    eventsViewsContainer.arrangedSubviews.forEach { $0.removeFromSuperview() }
    if card {
        createBusyCard()
    }
}

func createBusyCard() {
    let customView = BusyCardView()
    
    customView.didPressAddNewKid = {
        self.didPressAddNewKid?()
    }
    customView.didPressRemoveBusy = {
        self.didPressRemoveBusy?()
    }
    
    eventsViewsContainer.addArrangedSubview(customView)
}

And here's code for FlowLayout:

    class FlowLayout: UICollectionViewFlowLayout {

required init(minimumInteritemSpacing: CGFloat = 0, minimumLineSpacing: CGFloat = 0, sectionInset: UIEdgeInsets = .zero) {
    super.init()

    estimatedItemSize = UICollectionViewFlowLayout.automaticSize
    self.minimumInteritemSpacing = minimumInteritemSpacing
    self.minimumLineSpacing = minimumLineSpacing
    self.sectionInset = sectionInset
    sectionInsetReference = .fromSafeArea
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    let layoutAttributes = super.layoutAttributesForElements(in: rect)!.map { $0.copy() as! UICollectionViewLayoutAttributes }
    guard scrollDirection == .vertical else { return layoutAttributes }

    // Filter attributes to compute only cell attributes
    let cellAttributes = layoutAttributes.filter({ $0.representedElementCategory == .cell })

    // Group cell attributes by row (cells with same vertical center) and loop on those groups
    for (_, attributes) in Dictionary(grouping: cellAttributes, by: { ($0.center.y / 10).rounded(.up) * 10 }) {
        // Set the initial left inset
        var leftInset = sectionInset.left

        // Loop on cells to adjust each cell's origin and prepare leftInset for the next cell
        for attribute in attributes {
            attribute.frame.origin.x = leftInset
            leftInset = attribute.frame.maxX + minimumInteritemSpacing
        }
    }

    return layoutAttributes
}}
Taras Tomchuk
  • 301
  • 7
  • 15
  • You need to provide more information. How are you setting the "dynamic height" of your collection view? What properties and constraints are you giving to your stack view? – DonMag Nov 16 '20 at 13:52
  • There are no height constraints on stack view or collection view, only leading-trailing, top-bottom. I determine height of collection view by creation of custom class, i used this SO answer - https://stackoverflow.com/a/59275675/8945677 – Taras Tomchuk Nov 16 '20 at 15:38
  • Since you are putting your `CustomUIView.xib` *inside a stack view*, presumably you are adding other UI elements to that stack view. I think you'll need to show the code you are using to instantiate and add those views, as well as how you're loading and populating your collection view from the xib. You also say: *"if I place that UICollectionView directly into that table view cell"* .. and *"if I place that CustomUIView.xib somewhere in simple page with scroll view"* ... what about `CustomUIView` by itself in the cell? – DonMag Nov 16 '20 at 15:49
  • That custom view has only one element apart from collection - divider view with static height of 20pt. If I place that custom view without collection view - table view with stack view works fine and sets it's row height just fine. I have edited my question showing code. – Taras Tomchuk Nov 16 '20 at 16:10
  • 1
    Very possibly the height of your collection view has not yet been determined when the table view lays out the cell with the stack view. Can you put together a [mre] ? – DonMag Nov 16 '20 at 16:19
  • Just checked code with prints and yeah, you are right. Content size is 0 when table view loads it's cell, how can I fix that? Do you still need example? – Taras Tomchuk Nov 16 '20 at 16:37
  • Take a look at this answer (don't know if the OP ever cam back to look at it). If that doesn't help (or at least point you in the right direction), then yeah, I'd need to look at as minimal of a sample as you can provide. – DonMag Nov 16 '20 at 16:44
  • Link to answer would be enough for me. Just don't want to waste your time, you already helped a lot, thanks! – Taras Tomchuk Nov 16 '20 at 16:59

0 Answers0