简体   繁体   中英

RxSwift + canMoveRowAt

I'm using RxSwift (RxCocoa) to populate my tableView cells

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

This way I have no access to tableView's dataSource's method

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

But I need to specify which rows are movable for

tableView.rx.itemMoved

How can I restrict which rows should not be able to drag around? I would prefer avoid using RxDataSources

In order to do this, you need to do one of two things. Either pull in the RxDataSource Cocoapod and use one of the TableViewSectionedDataSource subclasses or make your own data source.

It's not hard to make a data source. Here's an example: https://github.com/dtartaglia/RxMultiCounter/blob/master/RxMultiCounter/RxExtensions/RxSimpleAnimatableDataSource.swift I used DifferenceKit in mine, but if you want to be super simple, you can just call tableView.reloadData() in your func tableView(_:observedEvent) method.

Here's an example:

//
//  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 = []
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM