📂
RxSwift
  • RxSwift 中文文档
  • 1. 为什么要使用 RxSwift?
  • 2. 你好 RxSwift!
  • 3. 函数响应式编程
    • 3.1 函数式编程
    • 3.2 函数式编程 -> 函数响应式编程
    • 3.3 数据绑定
  • 4. RxSwift 核心
    • 4.1 Observable - 可监听序列
      • Single
      • Completable
      • Maybe
      • Driver
      • Signal
      • ControlEvent
    • 4.2 Observer - 观察者
      • AnyObserver
      • Binder
    • 4.3 Observable & Observer 既是可监听序列也是观察者
      • AsyncSubject
      • PublishSubject
      • ReplaySubject
      • BehaviorSubject
      • Variable(已弃用)
      • ControlProperty
    • 4.4 Operator - 操作符
    • 4.5 Disposable - 可被清除的资源
    • 4.6 Schedulers - 调度器
    • 4.7 Error Handling - 错误处理
  • 5. 如何选择操作符?
    • amb
    • buffer
    • catchError
    • combineLatest
    • concat
    • concatMap
    • connect
    • create
    • debounce
    • debug
    • deferred
    • delay
    • delaySubscription
    • dematerialize
    • distinctUntilChanged
    • do
    • elementAt
    • empty
    • error
    • filter
    • flatMap
    • flatMapLatest
    • from
    • groupBy
    • ignoreElements
    • interval
    • just
    • map
    • merge
    • materialize
    • never
    • observeOn
    • publish
    • reduce
    • refCount
    • repeatElement
    • replay
    • retry
    • sample
    • scan
    • shareReplay
    • single
    • skip
    • skipUntil
    • skipWhile
    • startWith
    • subscribeOn
    • take
    • takeLast
    • takeUntil
    • takeWhile
    • timeout
    • timer
    • using
    • window
    • withLatestFrom
    • zip
  • 6. 更多示例
    • ImagePicker - 图片选择器
    • TableViewSectionedViewController - 多层级的列表页
    • Calculator - 计算器
  • 7. RxSwift 常用架构
    • 7.1 MVVM
      • Github Signup(示例)
    • 7.2 RxFeedback
      • Github Search(示例)
    • 7.3 ReactorKit
      • Github Search(示例)
  • 8. RxSwift 生态系统
  • 9. 学习资源
  • 10. 关于本文档
    • 10.1 文档更新日志
  • 食谱
    • RxSwift 5 更新了什么?
    • RxRelay
    • 纯函数
    • 附加作用
    • 共享附加作用
Powered by GitBook
On this page
  • 简介
  • 整体结构
  • 参考

Was this helpful?

  1. 6. 更多示例

TableViewSectionedViewController - 多层级的列表页

PreviousImagePicker - 图片选择器NextCalculator - 计算器

Last updated 4 years ago

Was this helpful?

演示如何使用 来布局列表页,你可以在这里下载。

简介

这是一个多层级列表页,它主要需要完成这些需求:

  • 每个 Section 显示对应的标题

  • 每个 Cell 显示对应的元素以及行号

  • 根据 Cell 的 indexPath 控制行高

  • 当 Cell 被选中时,显示一个弹框

整体结构

以上这些需求,只需要一页代码就能完成:

class SimpleTableViewExampleSectionedViewController
    : ViewController
    , UITableViewDelegate {
    @IBOutlet weak var tableView: UITableView!

    let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Double>>(
        configureCell: { (_, tv, indexPath, element) in
            let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
            cell.textLabel?.text = "\(element) @ row \(indexPath.row)"
            return cell
        },
        titleForHeaderInSection: { dataSource, sectionIndex in
            return dataSource[sectionIndex].model
        }
    )

    override func viewDidLoad() {
        super.viewDidLoad()

        let dataSource = self.dataSource

        let items = Observable.just([
            SectionModel(model: "First section", items: [
                    1.0,
                    2.0,
                    3.0
                ]),
            SectionModel(model: "Second section", items: [
                    1.0,
                    2.0,
                    3.0
                ]),
            SectionModel(model: "Third section", items: [
                    1.0,
                    2.0,
                    3.0
                ])
            ])


        items
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)

        tableView.rx
            .itemSelected
            .map { indexPath in
                return (indexPath, dataSource[indexPath])
            }
            .subscribe(onNext: { pair in
                DefaultWireframe.presentAlert("Tapped `\(pair.1)` @ \(pair.0)")
            })
            .disposed(by: disposeBag)

        tableView.rx
            .setDelegate(self)
            .disposed(by: disposeBag)
    }

    // to prevent swipe to delete behavior
    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
        return .none
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 40
    }
}

我们首先创建一个 dataSource: RxTableViewSectionedReloadDataSource<SectionModel<String, Double>>:

let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Double>>(
    configureCell: { (_, tv, indexPath, element) in
        let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
        cell.textLabel?.text = "\(element) @ row \(indexPath.row)"
        return cell
    },
    titleForHeaderInSection: { dataSource, sectionIndex in
        return dataSource[sectionIndex].model
    }
)

通过使用这个辅助类型,我们就不用执行数据源代理方法,而只需要提供必要的配置函数就可以布局列表页了。

第一个函数 configureCell 是用来配置 Cell 的显示,而这里的参数 element 就是 SectionModel<String, Double> 中的 Double。

第二个函数 titleForHeaderInSection 是用来配置 Section 的标题,而 dataSource[sectionIndex].model 就是 SectionModel<String, Double> 中的 String。

然后为列表页订制一个多层级的数据源 items: Observable<[SectionModel<String, Double>]>,用这个数据源来绑定列表页。

这里 SectionModel<String, Double> 中的 String 是用来显示 Section 的标题。而 Double 是用来绑定对应的 Cell。假如我们的列表页是用来显示通讯录的,并且通讯录通过首字母来分组。那么应该把数据定义为 SectionModel<String, Person>,然后用首字母 String 来显示 Section 标题,用联系人 Person 来显示对应的 Cell。

由于 SectionModel<Section, ItemType> 是一个范型,所以我们可以用它来定义任意类型的 Section 以及 Item。

最后:

override func viewDidLoad() {
    super.viewDidLoad()

    ...

    tableView.rx
        .setDelegate(self)
        .disposed(by: disposeBag)
}

...

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 40
}

这个是用来控制行高的,tableView.rx.setDelegate(self)... 将自己设置成 tableView 的代理,通过 heightForHeaderInSection 方法提供行高。

参考

RxDataSources
just
map
RxDataSources
这个例子