У меня есть представление, которое структурировано следующим образом
-Tableview
- TableviewCell
- UICollectionView
- UICollectionViewCell
ячейка uicollectionview определяет тег выравнивания по левому краю с collectionViewFlowLayout следующим образом
class Row {
var attributes = [UICollectionViewLayoutAttributes]()
var spacing: CGFloat = 0
init(spacing: CGFloat) {
self.spacing = spacing
}
func add(attribute: UICollectionViewLayoutAttributes) {
attributes.append(attribute)
}
func tagLayout(collectionViewWidth: CGFloat) {
let padding = 0
var offset = padding
for attribute in attributes {
attribute.frame.origin.x = CGFloat(offset)
offset += Int(attribute.frame.width + spacing)
}
}
}
class LeftAlignTagCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let attributes = super.layoutAttributesForElements(in: rect) else {
return nil
}
var rows = [Row]()
var currentRowY: CGFloat = -1
for attribute in attributes {
if currentRowY != attribute.frame.origin.y {
currentRowY = attribute.frame.origin.y
rows.append(Row(spacing: 4))
}
rows.last?.add(attribute: attribute)
}
rows.forEach {
$0.tagLayout(collectionViewWidth: collectionView?.frame.width ?? 0)
}
return rows.flatMap { $0.attributes }
}
}
это код в источнике данных cellForRow в ViewController, который обрабатывает табличное представление
let cell = tableView.dequeueReusableCell(withIdentifier: "CollectionTableViewCell") as? CollectionTableViewCell
cell?.setupCell(showFirstItem: true, showSecondItem: true)
cell?.collectionView.reloadData()
cell?.layoutIfNeeded()
let height = cell?.collectionView.collectionViewLayout.collectionViewContentSize.height
cell?.collectionViewHeightConstraint.constant = height ?? 0
я уже вызывал layoutIfNeeded() перед доступом к высоте размера содержимого коллекции и назначал высоту содержимого в ограничение высоты коллекции. я уже установил для isScrollEnabled значение false.
а в CollectionTableViewCell это выглядит так
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint! // Required priority (1000)
private var collectionItem: [String] = []
override func awakeFromNib() {
super.awakeFromNib()
setupCollectionView()
collectionView.dataSource = self
collectionView.delegate = self
let layout = LeftAlignTagCollectionViewFlowLayout()
layout.estimatedItemSize = CGSize(width: 140, height: 40)
collectionView.collectionViewLayout = layout
}
func setupCell(showFirstItem: Bool, showSecondItem: Bool) {
setupCollectionItem()
}
private func setupCollectionItem(showFirstItem: Bool, showSecondItem: Bool) {
collectionItem = []
if showFirstItem {
let data = "TagNumber1"
collectionItem.append(data)
}
if showSecondItem {
let data = "TagNumber2"
collectionItem.append(data)
}
}
extension CollectionTableViewCell: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
private func setupCollectionView() {
collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CollectionViewCell")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return collectionItem.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as? CollectionViewCell
cell?.configCell(model: collectionItem[indexPath.row], maxWidth: collectionView.frame.width - 8)
cell?.setNeedsLayout()
cell?.layoutIfNeeded()
return cell ?? UICollectionViewCell()
}
}
Таким образом, когда я запускаю приведенный выше код, он выдает неправильную высоту размера содержимого при первой загрузке, скажем, около 86,0, но после прокрутки или перезагрузки таблицы во второй раз (у меня есть два раза перезагрузка таблицы, так как есть два метода для вызова API в этот ViewController) он дает правильное число, скажем, цель, которую я хочу, составляет 24,0, поэтому при изменении с первого значения 86,0 на 24,0 это дает сбой в uitableviewcell. и я не могу скрыть представление таблицы, пока не завершу процесс расчета высоты представления коллекции. Еще один момент: если у меня есть только один элемент в collectionItem, он дает правильную высоту содержимого! но когда он превращается в два элемента, проблема проявляется.
жду вашего предложения, спасибо
Это по своей сути проблематично по нескольким причинам...
Во-первых, представления коллекций имеют несколько основных преимуществ:
при написании кода для «автоматического размера» представления коллекции оба этих преимущества отбрасываются.
Во-вторых, при первом создании экземпляра ячейки табличного представления он не знает, какой будет его фактическая ширина. Поэтому, когда представление коллекции размещает свои ячейки, оно использует ту ширину, с которой оно начинается, с которой оно настроено, например, в качестве прототипа ячейки в раскадровке, оно будет использовать ширину из раскадровки.
Если вы ищете uicollectionview inside uitableviewcell dynamic height
, вы найдете множество обсуждений и попыток заставить это работать с переменным успехом.
Однако, поскольку, как упоминалось выше, вы являетесь не используется двумя «лучшими функциями» представлений коллекций, вы можете использовать другой подход.
Взгляните на этот ответ на аналогичный вопрос «раскладка тегов». Возможно, вам будет проще работать с: https://stackoverflow.com/a/60588546/6257435