Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxSwift and How To Make Simple TableViewController?

Tags:

swift

rx-swift

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?"

like image 674
finneycanhelp Avatar asked Dec 05 '15 23:12

finneycanhelp


1 Answers

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" enter image description here

like image 58
finneycanhelp Avatar answered Nov 12 '22 04:11

finneycanhelp