RxDataSources 在数据源内容的每次更改时闪烁
RxDataSources flashing and flickering on every change in the datasource content
最初,应用程序显示带有一个部分的 UIViewCollection,然后在收到内容后出现新的部分。用户滚动集合,新部分添加到集合底部。
我使用 MVVM,因此在我的 ViewModel 中,我向内容数组 (model.content) 添加了一个新部分,然后通知发布者绑定到 collectionView.rx.items(dataSource: self.dataSource ).
所以每次我添加该部分时,集合都会闪烁,并且所有单元格都会重新加载,这让用户体验到一切都在闪烁、闪烁、图片消失和出现。有没有办法不重新加载所有集合,而只重新加载差异。我认为默认情况下它应该这样工作。也许通知 BehaviorSubject 的方法是错误的想法?
我也尝试使用 RxTableViewSectionedAnimatedDataSource,但这样一来,所有内容都会消失,并在添加每个新部分后将用户移动到集合视图的最顶部。
请问如果我只在底部添加一个部分为什么要重新加载所有集合,如何防止它?
typealias ContentDataSource = RxCollectionViewSectionedReloadDataSource<ContentSection>
class ContentViewController: BaseViewController<ContentViewModel> {
func setupBindings() {
viewModel?.sectionItemsSubject
.bind(to: collectionView.rx.items(dataSource: self.dataSource))
.disposed(by: self.disposeBag)
}
}
class ContentViewModel: BaseViewModel<ContentModel> {
lazy var sectionItemsSubject = BehaviorSubject<[ContentSection]>(value: model.content)
func updateGeneratedSection(_ section: ContentSection) {
model.content.append(item)
sectionItemsSubject.onNext(self.model.content)
}
}
struct ContentModel {
var content: [ContentSection] = []
}
编辑:
struct ContentSection {
var id: String
var items: [Item]
var order: Int
}
extension ContentSection: SectionModelType {
typealias Item = ItemCellModel
init(original: ContentSection, items: [ItemCellModel]) {
self = original
self.items = items
}
}
struct ItemCellModel {
let id: String
let img: String
init(id: String, img: String) {
self.id = id
self.img = img
}
}
您的模型可能不符合正确所需的协议,差异检查器无法识别它们相同的单元格模型,因此它会再次呈现整个集合视图。
请参阅相关文档:
‘’’
支持扩展您的项目和部分结构
只需使用 IdentifiableType 和 Equatable 扩展您的项目,并使用 AnimatableSectionModelType 扩展您的部分
‘’’
https://github.com/RxSwiftCommunity/RxDataSources
另外你可以按照这个例子 - https://bytepace.medium.com/bring-tables-alive-with-rxdatasources-rxswift-part-1-db050fbc2cf6.
CloudBalancing 的回答是正确的。您的 ContentSection 类型错误...试试这个:
typealias ContentSection = AnimatableSectionModel<ContentSectionModel, ItemCellModel>
struct ContentSectionModel: IdentifiableType {
var identity: String
var order: Int
}
struct ItemCellModel: IdentifiableType, Equatable {
let identity: String
let img: String
}
最初,应用程序显示带有一个部分的 UIViewCollection,然后在收到内容后出现新的部分。用户滚动集合,新部分添加到集合底部。
我使用 MVVM,因此在我的 ViewModel 中,我向内容数组 (model.content) 添加了一个新部分,然后通知发布者绑定到 collectionView.rx.items(dataSource: self.dataSource ).
所以每次我添加该部分时,集合都会闪烁,并且所有单元格都会重新加载,这让用户体验到一切都在闪烁、闪烁、图片消失和出现。有没有办法不重新加载所有集合,而只重新加载差异。我认为默认情况下它应该这样工作。也许通知 BehaviorSubject 的方法是错误的想法?
我也尝试使用 RxTableViewSectionedAnimatedDataSource,但这样一来,所有内容都会消失,并在添加每个新部分后将用户移动到集合视图的最顶部。
请问如果我只在底部添加一个部分为什么要重新加载所有集合,如何防止它?
typealias ContentDataSource = RxCollectionViewSectionedReloadDataSource<ContentSection>
class ContentViewController: BaseViewController<ContentViewModel> {
func setupBindings() {
viewModel?.sectionItemsSubject
.bind(to: collectionView.rx.items(dataSource: self.dataSource))
.disposed(by: self.disposeBag)
}
}
class ContentViewModel: BaseViewModel<ContentModel> {
lazy var sectionItemsSubject = BehaviorSubject<[ContentSection]>(value: model.content)
func updateGeneratedSection(_ section: ContentSection) {
model.content.append(item)
sectionItemsSubject.onNext(self.model.content)
}
}
struct ContentModel {
var content: [ContentSection] = []
}
编辑:
struct ContentSection {
var id: String
var items: [Item]
var order: Int
}
extension ContentSection: SectionModelType {
typealias Item = ItemCellModel
init(original: ContentSection, items: [ItemCellModel]) {
self = original
self.items = items
}
}
struct ItemCellModel {
let id: String
let img: String
init(id: String, img: String) {
self.id = id
self.img = img
}
}
您的模型可能不符合正确所需的协议,差异检查器无法识别它们相同的单元格模型,因此它会再次呈现整个集合视图。 请参阅相关文档:
‘’’ 支持扩展您的项目和部分结构 只需使用 IdentifiableType 和 Equatable 扩展您的项目,并使用 AnimatableSectionModelType 扩展您的部分 ‘’’
https://github.com/RxSwiftCommunity/RxDataSources
另外你可以按照这个例子 - https://bytepace.medium.com/bring-tables-alive-with-rxdatasources-rxswift-part-1-db050fbc2cf6.
CloudBalancing 的回答是正确的。您的 ContentSection 类型错误...试试这个:
typealias ContentSection = AnimatableSectionModel<ContentSectionModel, ItemCellModel>
struct ContentSectionModel: IdentifiableType {
var identity: String
var order: Int
}
struct ItemCellModel: IdentifiableType, Equatable {
let identity: String
let img: String
}