RxSwift and How To Make Simple TableViewController?

15,634

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

Share:
15,634
finneycanhelp
Author by

finneycanhelp

I love people, creating solutions, and technology.

Updated on June 19, 2022

Comments

  • finneycanhelp
    finneycanhelp almost 2 years

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