首页 > 解决方案 > RXSwift - RxCollectionViewSectionedReloadDataSource - 拖放移动(重新排序)

问题描述

我曾经RxCollectionViewSectionedReloadDataSource将我的数据加载到UICollectionView.

let dataSource = RxCollectionViewSectionedReloadDataSource<SectionModel<String, WorkGroup>>(
            configureCell: { (_, collectionView, indexPath, item) in
                guard let cell = collectionView
                        .dequeueReusableCell(withReuseIdentifier: WorkGroupCell.identifier, for: indexPath) as? WorkGroupCell else {
                            return WorkGroupCell()
                        }
                cell.viewModel = item
                return cell
            }
        )
        
        viewModel.items.bind(to: tileCollectonView.rx.items(dataSource: dataSource)).disposed(by: disposeBag)
 
        tileCollectonView.rx.setDelegate(self).disposed(by: disposeBag)

使用上面的代码我可以显示数据。但我想拖放(重新排序)单元格。

请让我知道如何使用RxSwift.

帮助将不胜感激。

标签: iosxcodeuicollectionviewrx-swift

解决方案


通常情况下,您需要一个状态机。

涉及的逻辑非常简单:

struct State<Item> {
    var items: [Item] = []
}

func state<Item>(initialState: State<Item>, itemMoved: Observable<ItemMovedEvent>) -> Observable<State<Item>> {
    itemMoved
        .scan(into: initialState) { (state, itemMoved) in
            state.items.move(from: itemMoved.sourceIndex.row, to: itemMoved.destinationIndex.row)
        }
        .startWith(initialState)
}

extension Array
{
    mutating func move(from oldIndex: Index, to newIndex: Index) {
        if oldIndex == newIndex { return }
        if abs(newIndex - oldIndex) == 1 { return self.swapAt(oldIndex, newIndex) }
        self.insert(self.remove(at: oldIndex), at: newIndex)
    }
}

以上使用ItemMovedEventRxCocoa 提供的表视图。为了为集合视图创建类似的东西,您需要将其包装UICollectionViewDragDelegate在委托代理中。可以在此处找到有关如何执行此操作的文章:将 Swift 委托转换为 RxSwift 可观察对象


推荐阅读