RXSwift collectionView.indexPathsForVisibleItems 为空
RXSwift collectionView.indexPathsForVisibleItems is empty
我是 RXSwift 的新手。所以基本上我只想在最后一个单元格在我的 collectionView 中可见时向右移动,但是 visibleIndexPaths 总是 return 一个空列表,如果我尝试在 #1 处获取 visibleIndexPaths 它会工作正常,但不是在 #2
工作
一个可能的原因是我更新dataSource后,collectionView被通知重新加载Data,然后我试图在加载完成之前获取visibleIndexPaths?
ViewController
的部分代码
class PerfectDayDiaryPopUpContentViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var imageCollectionView: UICollectionView!
private var viewModel: PerfectDayDiaryPopUpContentViewModel
private let disposeBag = DisposeBag()
func bind() {
self.viewModel.dataSource
.bind(to: self.imageCollectionView.rx.items) { (collectionView, row, image) -> UICollectionViewCell in
// #1 wroking well
print(self.imageCollectionView.indexPathsForVisibleItems)
return self.renderCell(collectionView: collectionView, row: row, image: image)
}
.disposed(by: self.disposeBag)
self.viewModel.dataSource
.subscribe { [weak self] images in
if self != nil, let images = images.element {
let lastImageIndexPath = IndexPath(row: images.count - 1, section: 0)
// #2 not working
let visibleIndexPaths = self!.imageCollectionView.indexPathsForVisibleItems
let shouldMoveToRight = visibleIndexPaths.contains(lastImageIndexPath)
if shouldMoveToRight {
self!.imageCollectionView.scrollToItem(at: lastImageIndexPath, at: .left, animated: true)
}
}
}
.disposed(by: self.disposeBag)
}
}
删除按钮动作绑定部分代码
cell.deleteButton.rx
.controlEvent(.touchUpInside)
.bind {
self.viewModel.lastImages = self.viewModel.images.value
var images = self.viewModel.images.value
images.remove(element: image)
self.viewModel.images.accept(images)
self.viewModel.upateDataSource()
self.imageCollectionView.layoutIfNeeded()
}
.disposed(by: self.disposeBag)
视图模型
class PerfectDayDiaryPopUpContentViewModel: NewPopUpContentViewModel {
public let content: BehaviorRelay<String>
public let images: BehaviorRelay<[UIImage]>
public let dataSource: BehaviorRelay<[UIImage]>
public let addImageIdentifier: String = "AddNewImage"
public let addImage = UIImage(named: "AddImage-HD")!
public var lastImages: [UIImage] = []
private let dataManager = DiaryDataManager()
private let disposeBag = DisposeBag()
init() {
self.addImage.accessibilityIdentifier = self.addImageIdentifier
self.content = BehaviorRelay<String>(value: "")
self.images = BehaviorRelay<[UIImage]>(value: [UIImage]())
self.dataSource = BehaviorRelay<[UIImage]>(value: [self.addImage])
}
init(diary: Diary) {
self.addImage.accessibilityIdentifier = self.addImageIdentifier
self.content = BehaviorRelay<String>(value: diary.getContent())
self.images = BehaviorRelay<[UIImage]>(value: diary.getImages())
self.dataSource = BehaviorRelay<[UIImage]>(value: [self.addImage])
}
public func upateDataSource() {
let images = self.images.value
if images.count < 8 {
self.addImage.accessibilityIdentifier = self.addImageIdentifier
self.dataSource.accept(images + [self.addImage])
} else {
self.dataSource.accept(images)
}
}
public func saveDiary() {
self.dataManager.saveDiary(date: CustomDate.current, content: self.content.value, images: self.images.value)
}
}
好的,我明白了,这个问题与 RXswift 无关
我刚刚添加了 layoutIfNeeded() 并且有效
self.viewModel.dataSource
.subscribe { [weak self] images in
UIView.animate(withDuration: 0.3) {
self?.imageCollectionView.layoutIfNeeded()
}
if self != nil, let images = images.element {
let lastImageIndexPath = IndexPath(row: images.count - 1, section: 0)
// #2 not working
let visibleIndexPaths = self!.imageCollectionView.indexPathsForVisibleItems
let shouldMoveToRight = visibleIndexPaths.contains(lastImageIndexPath)
if shouldMoveToRight {
self!.imageCollectionView.scrollToItem(at: lastImageIndexPath, at: .left, animated: true)
}
}
}
.disposed(by: self.disposeBag)
我是 RXSwift 的新手。所以基本上我只想在最后一个单元格在我的 collectionView 中可见时向右移动,但是 visibleIndexPaths 总是 return 一个空列表,如果我尝试在 #1 处获取 visibleIndexPaths 它会工作正常,但不是在 #2
工作一个可能的原因是我更新dataSource后,collectionView被通知重新加载Data,然后我试图在加载完成之前获取visibleIndexPaths?
ViewController
的部分代码class PerfectDayDiaryPopUpContentViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var imageCollectionView: UICollectionView!
private var viewModel: PerfectDayDiaryPopUpContentViewModel
private let disposeBag = DisposeBag()
func bind() {
self.viewModel.dataSource
.bind(to: self.imageCollectionView.rx.items) { (collectionView, row, image) -> UICollectionViewCell in
// #1 wroking well
print(self.imageCollectionView.indexPathsForVisibleItems)
return self.renderCell(collectionView: collectionView, row: row, image: image)
}
.disposed(by: self.disposeBag)
self.viewModel.dataSource
.subscribe { [weak self] images in
if self != nil, let images = images.element {
let lastImageIndexPath = IndexPath(row: images.count - 1, section: 0)
// #2 not working
let visibleIndexPaths = self!.imageCollectionView.indexPathsForVisibleItems
let shouldMoveToRight = visibleIndexPaths.contains(lastImageIndexPath)
if shouldMoveToRight {
self!.imageCollectionView.scrollToItem(at: lastImageIndexPath, at: .left, animated: true)
}
}
}
.disposed(by: self.disposeBag)
}
}
删除按钮动作绑定部分代码
cell.deleteButton.rx
.controlEvent(.touchUpInside)
.bind {
self.viewModel.lastImages = self.viewModel.images.value
var images = self.viewModel.images.value
images.remove(element: image)
self.viewModel.images.accept(images)
self.viewModel.upateDataSource()
self.imageCollectionView.layoutIfNeeded()
}
.disposed(by: self.disposeBag)
视图模型
class PerfectDayDiaryPopUpContentViewModel: NewPopUpContentViewModel {
public let content: BehaviorRelay<String>
public let images: BehaviorRelay<[UIImage]>
public let dataSource: BehaviorRelay<[UIImage]>
public let addImageIdentifier: String = "AddNewImage"
public let addImage = UIImage(named: "AddImage-HD")!
public var lastImages: [UIImage] = []
private let dataManager = DiaryDataManager()
private let disposeBag = DisposeBag()
init() {
self.addImage.accessibilityIdentifier = self.addImageIdentifier
self.content = BehaviorRelay<String>(value: "")
self.images = BehaviorRelay<[UIImage]>(value: [UIImage]())
self.dataSource = BehaviorRelay<[UIImage]>(value: [self.addImage])
}
init(diary: Diary) {
self.addImage.accessibilityIdentifier = self.addImageIdentifier
self.content = BehaviorRelay<String>(value: diary.getContent())
self.images = BehaviorRelay<[UIImage]>(value: diary.getImages())
self.dataSource = BehaviorRelay<[UIImage]>(value: [self.addImage])
}
public func upateDataSource() {
let images = self.images.value
if images.count < 8 {
self.addImage.accessibilityIdentifier = self.addImageIdentifier
self.dataSource.accept(images + [self.addImage])
} else {
self.dataSource.accept(images)
}
}
public func saveDiary() {
self.dataManager.saveDiary(date: CustomDate.current, content: self.content.value, images: self.images.value)
}
}
好的,我明白了,这个问题与 RXswift 无关
我刚刚添加了 layoutIfNeeded() 并且有效
self.viewModel.dataSource
.subscribe { [weak self] images in
UIView.animate(withDuration: 0.3) {
self?.imageCollectionView.layoutIfNeeded()
}
if self != nil, let images = images.element {
let lastImageIndexPath = IndexPath(row: images.count - 1, section: 0)
// #2 not working
let visibleIndexPaths = self!.imageCollectionView.indexPathsForVisibleItems
let shouldMoveToRight = visibleIndexPaths.contains(lastImageIndexPath)
if shouldMoveToRight {
self!.imageCollectionView.scrollToItem(at: lastImageIndexPath, at: .left, animated: true)
}
}
}
.disposed(by: self.disposeBag)