更改单元格的背景是将集合视图偏移量移动到第一个元素

Changing cell's background is moving collection view offset to 1st element

我有带自动调整单元格大小的水平集合视图。我是 RxSwift 的新手,无法弄清楚这段代码有什么问题。每当我单击任何元素集合视图时,都会将其设置为起点。我只有一个选择是在重新加载之前保存集合视图的偏移量,然后手动将集合视图偏移量设置为以前保存的,但这对我来说似乎是不好的做法。

这是我的手机:

class FilterCell: UICollectionViewCell {

   @IBOutlet weak var filterIcon: UIImageView!
   @IBOutlet weak var filterText: UILabel!

   func updateView(_ isSelected: Bool) {
      contentView.backgroundColor = isSelected ? .blue : .white
   }

   func updateData(icon: UIImage?, text: String?) {
      filterIcon.image = icon ?? filterIcon.image
      filterText.text = text ?? filterText.text
   }
}

这是细胞模型

struct FilterCellModel {
    let id: Int
    let image: String
    let text: String
    var isSelected: Bool = false
}

在视图模型中我只有单元格模型数组:

class LoginViewModel {

let usernameTextFieldPublishSubject = PublishSubject<String>()
let passwordTextFieldPublishSubject = PublishSubject<String>()

let filters = BehaviorRelay<[FilterCellModel]>(value: [
    FilterCellModel(id: 0, image: "filter-ic-1", text: "Extra filter"),
    FilterCellModel(id: 1, image: "filter-ic-1", text: "Different extra filter"),
    FilterCellModel(id: 2, image: "filter-ic-1", text: "Short filter"),
    FilterCellModel(id: 3, image: "filter-ic-1", text: "Lorem Ipsum"),
    FilterCellModel(id: 4, image: "filter-ic-1", text: "Lorem filter"),
    FilterCellModel(id: 5, image: "filter-ic-1", text: "Ipsum filter")
])

这就是我显示单元格并使用 RxSwift 更新它们的方式

loginViewModel.filters.bind(to: filterCollectionView.rx.items(cellIdentifier: "FilterCell", cellType: FilterCell.self)) { cv, item, cell in
        cell.updateData(icon: UIImage(named: item.image), text: item.text)
        cell.updateView(item.isSelected)
    }.disposed(by: bag)
    
    filterCollectionView.rx.itemSelected.subscribe(onNext: { index in
        var filters = self.loginViewModel.filters.value
        let isSelected = filters[index.item].isSelected
        filters[index.item].isSelected = !isSelected
        self.loginViewModel.filters.accept(filters)
    }).disposed(by: bag)

每次从 filters Observable 发出新值时,集合视图都会重新加载。这部分意味着它可以追溯到开始。所以解决这个问题的方法是,当用户选择一个项目时,你不会从 filters 发出新值。

有多种方法可以做到这一点。

  • 最简单的方法是从 FilterCellModel 类型中删除 isSelected 参数。而是通过其他方式跟踪选择了哪些项目。
  • 另一种选择是使用自定义数据源,它只重新加载状态已更改的项目。查看 RxDataSources 库以获取想法。