How can I create a RxSwift-style TableViewController?
I am trying to create a simple TableViewController that uses RxSwift and doesn't have any sections.
I have looked and played around with https://github.com/ReactiveX/RxSwift/blob/master/RxExample/RxExample/Examples/TableView/TableViewController.swift extensively.
I got the code down to only one section and using only users. However, it seems like I'm stuck with having a SectionModel.
//
// TableViewController.swift
// RxExample
//
// Created by carlos on 26/5/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
// modified by Mike Finney for a StackOverflow question
import UIKit
#if !RX_NO_MODULE
import RxSwift
import RxCocoa
#endif
class TableViewController: ViewController, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
var disposeBag = DisposeBag()
let users = Variable([User]())
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, User>>()
typealias Section = SectionModel<String, User>
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = self.editButtonItem()
users
.map { [ SectionModel(model: "ok", items: $0) ] }
.bindTo(tableView.rx_itemsWithDataSource(dataSource))
.addDisposableTo(disposeBag)
dataSource.cellFactory = { (tv, ip, user: User) in
let cell = tv.dequeueReusableCellWithIdentifier("Cell")!
cell.textLabel?.text = user.firstName + " " + user.lastName
return cell
}
// customization using delegate
// RxTableViewDelegateBridge will forward correct messages
tableView.rx_setDelegate(self)
.addDisposableTo(disposeBag)
tableView.rx_itemSelected
.subscribeNext { [unowned self] indexPath in
self.showDetailsForUserAtIndexPath(indexPath)
}
.addDisposableTo(disposeBag)
tableView.rx_itemDeleted
.subscribeNext { [unowned self] indexPath in
self.removeUser(indexPath)
}
.addDisposableTo(disposeBag)
RandomUserAPI.sharedAPI.getExampleUserResultSet()
.subscribeNext { [unowned self] array in
self.users.value = array
}
.addDisposableTo(disposeBag)
}
override func setEditing(editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
tableView.editing = editing
}
// MARK: Table view delegate ;)
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 0
}
// MARK: Navigation
private func showDetailsForUserAtIndexPath(indexPath: NSIndexPath) {
let sb = UIStoryboard(name: "Main", bundle: NSBundle(identifier: "RxExample-iOS"))
let vc = sb.instantiateViewControllerWithIdentifier("DetailViewController") as! DetailViewController
vc.user = getUser(indexPath)
self.navigationController?.pushViewController(vc, animated: true)
}
// MARK: Work over Variable
func getUser(indexPath: NSIndexPath) -> User {
var array: [User]
switch indexPath.section {
case 0:
array = users.value
default:
fatalError("Section out of range")
}
return array[indexPath.row]
}
func moveUserFrom(from: NSIndexPath, to: NSIndexPath) {
var user: User
var fromArray: [User]
var toArray: [User]
fromArray = users.value
user = fromArray.removeAtIndex(from.row)
users.value = fromArray
toArray = users.value
toArray.insert(user, atIndex: to.row)
users.value = toArray
}
func addUser(user: User) {
var array = users.value
array.append(user)
users.value = array
}
func removeUser(indexPath: NSIndexPath) {
var array: [User]
switch indexPath.section {
case 0:
array = users.value
array.removeAtIndex(indexPath.row)
users.value = array
default:
fatalError("Section out of range")
}
}
}
I don't want to even use a SectionModel if I can help it.
So perhaps another way to ask is "What is the non-section version of RxTableViewSectionedReloadDataSource?"
Around December 6th 2015, a new example was added to the RxSwift/RxExample. The View Controller to look at is SimpleTableViewExampleViewController.swift in the RxSwift code.
If you run the examples, select the one titled "Simplest table view example"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With