Reputation: 11
I am trying to create a collection view that has a simple cell with text, which means that the width and height of the cells should be dynamic. Since it should be able to be shorter/longer and the number of lines is n (Text comes from the service). As long as The cells width is not bigger than the collection it self, there is no problem. But if a long text should be presented it crashes.
It would only happen using .estimate as size, it wont if the cell take all the possible space
This is how the implementation looks like
Error:
Thread 1: "<UICollectionViewCompositionalLayout: 0x105b08470> ran into an error when computing the layout for section at index 0 in container <_UICollectionLayoutContainer: 0x600001756440 contentSize={353, 500}; contentInsets={0, 0, 0, 0}}>. Container calculated by applying insets ({0, 0, 0, 0}) from sectionInsetsReference \"safeArea\" to collection view frame {{0, 0}, {353, 500}}.\nError: NSCollectionLayoutItem created with invalid combination of spacing and size specified. This group cannot fit even a single item. Inspect the spacing and size of the items in this group and ensure that they fit into the group when its effective size is {333, 480}.\nGroup: <NSCollectionLayoutGroup 0x6000035082c0 size={.containerWidthFactor(1), .estimated(480)}>\n\t layoutDirection: .horizontal\n\t interItemSpacing=.fixed(4)\n\t subitems=\n\t\t <NSCollectionLayoutItem 0x600002620660 size={.estimated(32), .estimated(120)}>"
The collectionView is inside a UIView that works as wrapper and the view is inside a StackView like this:
stackView.addArrangedSubview(label)
stackView.addArrangedSubview(collectionViewWrapper)
stackView.backgroundColor = .white
collectionViewWrapper.translatesAutoresizingMaskIntoConstraints = false
let actionGruopViewHeight = collectionViewWrapper.heightAnchor.constraint(equalToConstant: 200)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
stackView.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -20),
collectionViewWrapper.widthAnchor.constraint(equalTo: stackView.widthAnchor),
actionGruopViewHeight
])
view.backgroundColor = .red
collectionViewWrapper.didLayoutAction = {
actionGruopViewHeight.constant = collectionViewWrapper.collectionView.contentSize.height
}
CollectionView wrapper:
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(ActionCell.self, forCellWithReuseIdentifier: ActionCell.reuseIdentifier)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .green
addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: topAnchor),
collectionView.trailingAnchor.constraint(equalTo: trailingAnchor),
collectionView.leadingAnchor.constraint(equalTo: leadingAnchor),
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
CollectionViewLayout:
private lazy var layout = UICollectionViewCompositionalLayout { [weak self] _, _ in
let itemSize = NSCollectionLayoutSize(widthDimension: .estimated(32), heightDimension: .estimated(120))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(480))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.interItemSpacing = .fixed(4)
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = .init(top: 10, leading: 10, bottom: 10, trailing: 10)
section.interGroupSpacing = 4
return section
}
Cell:
private lazy var textLabel: UILabel = {
let textLabel = UILabel()
textLabel.numberOfLines = 0
return textLabel
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(textLabel)
textLabel.translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .gray
NSLayoutConstraint.activate([
textLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
textLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
textLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
textLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
}
Did I do something wrong? is there a fix/workaround to avoid the crash?
Notice that it would be easy to reproduce with accessibility font sizes, since usually it would need 2 lines
Upvotes: 1
Views: 164