Я показываю результаты веб-запроса к пользовательскому API в UICollectionView с ячейками динамического размера. Однако, когда я вызываю reloadSections после извлечения данных, многие ячейки отображаются перекрывающимися.
По мере прокрутки представления ячейки отображаются на своих местах.
Я отследил ошибку вызова reloadSections в блоке завершения для моего веб-запроса. Используя жестко закодированный текст, представление коллекции правильно отображается с исходным макетом. Если reloadSections вызывается в блоке завершения, возникает ошибка. Ниже приведен соответствующий код:
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(UINib.init(nibName: "ExhibitionsCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "ExhibitionsCollectionViewCell")
layout.estimatedItemSize = CGSize(width: 1, height: 1)
collectionView.dataSource = exhibitionsDataSource
collectionView.delegate = self
store.fetchExhibitions {
(exhibitionsResult) -> Void in
switch exhibitionsResult {
case let .success(exhibitions):
print("Successfully found \(exhibitions.count) exhibitions.")
if exhibitions.first != nil {
self.exhibitionsDataSource.exhibitions = exhibitions
}
case let .failure(error):
print("Error fetching exhibitions: \(error)")
self.exhibitionsDataSource.exhibitions.removeAll()
}
// this is the line that produces the erroneous layout
self.collectionView.reloadSections(IndexSet(integer: 0))
}
}
Код, выполняющий веб-запрос:
func fetchExhibitions(completion: @escaping (ExhibitionsResult) -> Void) {
let url = WebAPI.exhibitionsURL
let request = URLRequest(url: url)
let task = session.dataTask(with: request) {
(data, response, error) -> Void in
let result = self.processExhibitionsRequest(data: data, error: error)
OperationQueue.main.addOperation {
completion(result)
}
}
task.resume()
}
Если есть какой-либо другой код, который был бы полезен для ответа на этот вопрос, дайте мне знать.
Обновление: я исправил проблему, реализовав следующий метод делегата UICollectionViewDelegateFlowLayout.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cell = collectionView.cellForItem(at: indexPath)
let height = cell?.contentView.bounds.height ?? 1
let width = cell?.contentView.bounds.width ?? 1
return CGSize(width: width, height: height)
}
Update2: после замены моих поддельных данных Lorem Ipsum на данные, фактически полученные с сервера, проблема возникла снова. Однако мне удалось окончательно решить проблему, просто переключив линию
self.collectionView.reloadSections(IndexSet(integer: 0))
to
self.reloadData()
Я бы подумал, что reloadSection(_:) просто выполняет то же действие, что и reloadData(), но для выбранных разделов и в документации, похоже, не указано иное... но в любом случае теперь это работает!