RxSwift 以及如何制作简单的 TableViewController?

Posted

技术标签:

【中文标题】RxSwift 以及如何制作简单的 TableViewController?【英文标题】:RxSwift and How To Make Simple TableViewController? 【发布时间】:2015-12-05 23:54:31 【问题描述】:

如何创建 RxSwift 风格的 TableViewController?

我正在尝试创建一个使用 RxSwift 并且没有任何部分的简单 TableViewController。

我已经广泛使用https://github.com/ReactiveX/RxSwift/blob/master/RxExample/RxExample/Examples/TableView/TableViewController.swift。

我只将代码缩减到一个部分,并且只使用用户。但是,我似乎无法使用 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 *** 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")
        
    


如果可以的话,我什至不想使用 SectionModel。

所以也许另一种方式是“RxTableViewSectionedReloadDataSource 的非节版本是什么?”

【问题讨论】:

答案可能与使用RxTableViewReactiveArrayDataSource有关。将确认。 仔细阅读:github.com/ReactiveX/RxSwift/blob/master/Documentation/… 和 github.com/ReactiveX/RxSwift/tree/master/RxDataSourceStarterKit 我复制了 RxTableViewReactiveArrayDataSource.swift 和 RxTableViewDataSourceType.swift 有两个编译问题 1) rxAbstractMethod() 和 2) bindingErrorToInterface(error)。 RxCocoa.swift 声明/定义它们。我错过了什么或应该做什么? 该问题的链接现在已断开。我相信高级版本的新位置在 RxDataSources github.com/RxSwiftCommunity/RxDataSources 【参考方案1】:

大约在 2015 年 12 月 6 日,RxSwift/RxExample 中添加了一个新示例。要查看的 View Controller 是 RxSwift 代码中的 SimpleTableViewExampleViewController.swift。

如果您运行示例,请选择标题为“最简单的表格视图示例”的示例

【讨论】:

以上是关于RxSwift 以及如何制作简单的 TableViewController?的主要内容,如果未能解决你的问题,请参考以下文章

哪个 RxSwift 运算符用于唯一发出的元素以及如何使用?

使用 rxSwift 中的 tableView 单元将数据从视图模型传递到视图控制器

RxSwift 如何将“清除所有”UIButton 添加到简单的电子表格示例

如何在 RxSwift 中为整个应用程序中的单元格和按钮设置动画?

如何使用 RxSwift 订阅数组更改?

使用 RxSwift/RxCocoa 制作的 TableView 在绑定到的变量中的数据更改后出现故障