Reputation: 6393
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
Upvotes: 1
Views: 918
Reputation: 33967
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 = []
}
Upvotes: 2