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
}}