swift - Swift:当要为一个部分呈现内容时,请指定一个有效的部分定义。这是客户端错误
问题描述
我目前正在使用集合视图和可区分的数据源开发一个简单的 IOS 应用程序。
每次更新源数据时,我都会初始化视图控制器配置中的所有内容并调用 reloadView 函数。
一旦我调用 reloadView 函数,应用程序就会崩溃并出现以下错误。但前提是集合视图之前是空的。如果那里已经有物品,那么一切都很好。
Assertion failure in -[_UICollectionCompositionalLayoutSolver _queryClientForSectionDefintionForSectionIndex:]
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid section definition. Please specify a valid section definition when content is to be rendered for a section. This is a client error.'
这就是我的代码的样子:
private func configureHierarchy() {
let layout = collectionViewHelper.createLayout(structure: self.structure)
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
collectionView.delegate = self
collectionView.register(RecentCollectionViewCell.self, forCellWithReuseIdentifier: RecentCollectionViewCell.reuseIdentifier)
collectionView.register(OverviewCollectionViewCell.self, forCellWithReuseIdentifier: OverviewCollectionViewCell.reuseIdentifier)
collectionView.register(MessageItemCollectionViewCell.self, forCellWithReuseIdentifier: MessageItemCollectionViewCell.reuseIdentifier)
view.addSubview(collectionView)
}
private func configureDataSource() {
dataSource = UICollectionViewDiffableDataSource<SectionType, Int>(collectionView: collectionView) {
(collectionView: UICollectionView, indexPath: IndexPath, cellIndex: Int) -> UICollectionViewCell? in
let sectionItem = self.structure[indexPath.section]
switch sectionItem.type{
//Returns a collection view cell of the specific type
case .recent:
return getRecentItemCell(...)
case .overview:
return getOverviewItemCell(...)
case .message:
return getMessageItemCell(...)
default:
return nil
}
}
}
我像这样应用快照
private func applySnapshot(structure:[SectionItem]) {
var snapshot = NSDiffableDataSourceSnapshot<SectionType, Int>()
var itemOffset = 0
for structurItem in structure {
snapshot.appendSections([structurItem.type])
snapshot.appendItems(Array(itemOffset..<itemOffset + structurItem.items))
itemOffset += structurItem.items
}
dataSource.apply(snapshot, animatingDifferences: false)
}
我在我的配置中这样做了一次
structure = createStructure()
configureHierarchy()
configureDataSource()
applySnapshot(structure: createStructure())
这是我每次数据变化时调用的reload函数(如果之前没有显示数据就会报错)
func reloadView() {
structure = createStructure()
applySnapshot(structure: structure)
}
任何想法为什么会这样?已经非常感谢了!
解决方案
就我而言, UICollectionViewCompositionalLayout 不会在内存中删除,当我的控制器已被删除时它会继续工作。
private func configureLayout() {
let layout = UICollectionViewCompositionalLayout { [weak self] (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
return self?.layoutSection(sectionIndex: sectionIndex, layoutEnvironment: layoutEnvironment)
}
self.collectionView.collectionViewLayout = layout
}
这是我的代码
推荐阅读
- python - 如何使用 LSTM 输入具有 128 个特征的 100 个时间步长和具有 128 个特征的 19000 个时间步长的输出
- c++ - 字符串中元音的数量 C++
- visual-studio-code - 如何在 Visual Studio Code 中关闭信息弹出窗口
- javascript - 如何在现有的 Javascript 对象中添加具有值的动态键?
- python - 在 Odoo 9 的编辑模式下,复选框上使用 Onchange 装饰器的方法无法正常工作
- python - 在评估多个列表的 for 循环中返回布尔值
- javascript - 如何使用移动 gps 让 Dark Sky API 工作
- javascript - 如何在 React-navigation/react-native 中隐藏后退按钮
- r - data.table shift 返回错误的值
- python - 带有计数聚合的 Pandas groupby