RxSwift + canMoveRowAt

时间:2018-12-19 14:41:28

标签: swift uitableview rx-swift rx-cocoa

我正在使用RxSwift(RxCocoa)填充tableView单元格

viewModel.cellsDriver.drive(tableView.rx.items) { ... }

这样,我无权访问tableView的dataSource的方法

func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool

但是我需要指定可移动的行

tableView.rx.itemMoved

如何限制不应拖动的行?我宁愿避免使用RxDataSources

1 个答案:

答案 0 :(得分:1)

为此,您需要执行以下两项操作之一。要么拉入RxDataSource Cocoapod并使用TableViewSectionedDataSource子类之一,要么创建自己的数据源。

创建数据源并不难。下面是一个示例:https://github.com/dtartaglia/RxMultiCounter/blob/master/RxMultiCounter/RxExtensions/RxSimpleAnimatableDataSource.swift我在我的系统中使用了DifferenceKit,但是如果您想变得非常简单,则可以在tableView.reloadData()方法中调用func tableView(_:observedEvent)

这是一个例子:

//
//  RxTableViewMovableRowDataSource.swift
//
//  Created by Daniel Tartaglia on 12/19/18.
//  Copyright © 2018 Daniel Tartaglia. MIT License.
//

import UIKit
import RxSwift
import RxCocoa


class RxTableViewMovableRowDataSource<E, Cell: UITableViewCell>: NSObject, RxTableViewDataSourceType, UITableViewDataSource {

    init(identifier: String, configure: @escaping (Int, E, Cell) -> Void, canMoveRowAt: ((Int, E) -> Bool)? = nil) {
        self.identifier = identifier
        self.configure = configure
        self.canMoveRowAt = canMoveRowAt
    }

    func tableView(_ tableView: UITableView, observedEvent: Event<[E]>) {
        values = observedEvent.element ?? []
        tableView.reloadData()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return values.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath) as! Cell
        let row = indexPath.row
        configure(row, values[row], cell)
        return cell
    }

    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        let row = indexPath.row
        return canMoveRowAt?(row, values[row]) ?? true
    }

    let identifier: String
    let configure: (Int, E, Cell) -> Void
    let canMoveRowAt: ((Int, E) -> Bool)?
    var values: Element = []
}