更改单元格的背景是将集合视图偏移量移动到第一个元素
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 库以获取想法。
我有带自动调整单元格大小的水平集合视图。我是 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 库以获取想法。