Я не знаю, почему так сложно создавать ячейки, которые могут адаптироваться к его содержанию.Это не должно нуждаться в таком большом количестве кода, я все еще не понимаю, почему UIKit
не может обработать это должным образом.
В любом случае, вот моя проблема ( Я отредактировал весь пост ):
У меня есть UICollectionViewCell
, который содержит UITableView
.
Вот мой sizeForItem
метод:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
var cellWidth: CGFloat = collectionView.bounds.size.width
var cellHeight: CGFloat = 0
let cellConfigurator = items[indexPath.item].cellConfigurator
if type(of: cellConfigurator).reuseId == "MoonCollectionViewCell" {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: type(of: cellConfigurator).reuseId, for: indexPath) as? MoonCollectionViewCell {
cell.contentView.layoutIfNeeded()
let size = cell.selfSizedTableView.intrinsicContentSize
cellHeight = size.height
}
}
return CGSize.init(width: cellWidth, height: cellHeight)
}
sizeForItem
вызывается раньше cellForItem
, это причина layoutIfNeeded
, потому что я не мог получитьправильный intrinsic content size
.
Я удалил XIB, как предложено, и спроектировал мой UICollectionViewCell в раскадровке.
Вот мой UICollectionViewCell, спроектированный в раскадровке (только UITableViewCell разработан вФайл XIB)
Я только добавил UITableView в UICollectionViewCell.
Я хочу, чтобы UICollectionViewCell
адаптировал свой размер в соответствии с высотойиз tableView
.
Теперь вот мой tableView
:
Я создал подкласс UITableView
(из этой записи )
class SelfSizedTableView: UITableView {
var maxHeight: CGFloat = UIScreen.main.bounds.size.height
override func reloadData() {
super.reloadData()
self.invalidateIntrinsicContentSize()
self.layoutIfNeeded()
}
override var intrinsicContentSize: CGSize {
let height = min(contentSize.height, maxHeight)
return CGSize(width: contentSize.width, height: height)
}
}
Обратите внимание, что у меня есть disabled scrolling
, у меня есть dynamic prototype
для ячеек tableView, стиль: grouped
.
РЕДАКТИРОВАТЬ: ПроверьтеМетод onfigure, он исходит из протокола, который я использовал для общей настройки всех моих UICollectionViewCell
func configure(data: [MoonImages]) {
selfSizedTableView.register(UINib.init(nibName: "MoonTableViewCell", bundle: nil), forCellReuseIdentifier: "MoonTableViewCell")
selfSizedTableView.delegate = self
selfSizedTableView.dataSource = moonDataSource
var frame = CGRect.zero
frame.size.height = .leastNormalMagnitude
selfSizedTableView.tableHeaderView = UIView(frame: frame)
selfSizedTableView.tableFooterView = UIView(frame: frame)
selfSizedTableView.maxHeight = 240.0
selfSizedTableView.estimatedRowHeight = 40.0
selfSizedTableView.rowHeight = UITableView.automaticDimension
moonDataSource.data.addAndNotify(observer: self) { [weak self] in
self?.selfSizedTableView.reloadData()
}
moonDataSource.data.value = data
}
FYI dataSource - пользовательский источник данных с динамическим значением(Generics) и шаблон наблюдателя для перезагрузки collection / tableView при заданных данных.
У меня также появляется это предупреждение при запуске приложения.
[CollectionView] Попытка обновить информацию о макете была обнаружена еще в процессе вычисления макета (т. Е. Повторный входящий вызов).Это приведет к неожиданному поведению или падению.Это может произойти, если проход макета инициируется при вызове делегата.
Любые советы или рекомендации о том, как мне следует это делать?
Поскольку я сталкиваюсь со странным поведением,это как мой sizeForItem использовать случайные значения.Высота UICollectionViewCell
не совпадает с высотой внутреннего размера UITableView
.
Если в моем UITableView
есть 2 строки, UICollectionView
не всегда равенв этом размере.Я действительно не знаю, как этого добиться ...
Должен ли я invalideLayout
?