UICollectionView внутри UITableViewCell НЕ динамически изменяет размер
У меня есть UICollectionView внутри UITableViewCell.
Я устанавливаю высоту строки UITableViewCell, чтобы быть динамическим:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Мой UICollectionView имеет переменное количество элементов:
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return items.count
}
Теперь вот последовательность событий, которая вызывает у меня головную боль:
- UITableView вызывает делегат cellForRowAt и удаляет UITableViewCell с динамической высотой
- В цикле NEXT UICollectionView внутри UITableViewCell вызывает свои делегаты numberOfItemsInSection и cellForItemAt для определения UICollectionView contentSize.
- Теперь уже слишком поздно, так как UITableViewCell уже был динамически изменен с UICollectionView, который не имеет ячеек, и поэтому высота UITablewViewCell слишком коротка и НЕ подходит для UICollectionView должным образом.
Я нашел уродливую работу, перезагружая UITableView, но мне совсем не нравится этот подход:
private func reloadCell() {
let when = DispatchTime.now()
DispatchQueue.main.asyncAfter(deadline: when) {
if let indexPath = self.chatViewController?.chatTableView.indexPath(for: self) {
self.tableView.reloadRows(at: [indexPath], with: .none)
}
}
}
Мой вопрос заключается в том, могу ли я заставить UICollectionView перезагрузить и немедленно вызвать его делегатов, чтобы высота UITableViewCell могла быть правильно рассчитана механизмом автоматического определения расположения?
1 ответ
В viewDidLoad добавьте наблюдателя для представления коллекции,
collectionView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.Old.union(NSKeyValueObservingOptions.New), context: self)
Теперь переопределитель наблюдает значение для keypath для управления обработчиком завершения перезагрузки представления коллекции через KVO.
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>)
{
// You will get here when the reloadData finished
}
Теперь в поле зрения "Исчезнуть" удалите наблюдателя, который был установлен для представления коллекции.
override func viewWillDisappear(_ animated: Bool) {
{
// remove collection view observer
}
Та же логика будет применена к табличному представлению, чтобы получить полностью видимую ячейку табличного представления, содержащую представление коллекции внутри нее.