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)