RxSwift 系列四、UITableView的使用

iOS開發必會技能 - RxSwift 系列四、UITableView的使用

前面我們講了最基礎的RxSwift知識點。

本來應該繼續講知識點。但是為了大家學的不那麼枯燥,我們現在開始講平時開發經常用到的一些控件。在期間穿插一些知識點。

今天我們將的是 iOS開發中最常用的UITableview控件。

一、基本用法

先上代碼:

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {

var tableView:UITableView!

let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

//創建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創建一個重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)

//初始化數據
let items = Observable.just([
"UILable的用法",
"UIText的用法",
"UIButton的用法"
])

//設置單元格數據(其實就是對 cellForRowAt 的封裝)
items.bind(to: tableView.rx.items) { (tableView, row, element) in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(row):\(element)"
return cell
}
.disposed(by: disposeBag)
}
}

cell選中事件

//獲取選中項的索引
tableView.rx.itemSelected.subscribe(onNext: { indexPath in
print("選中項的indexPath為:\(indexPath)")
}).disposed(by: disposeBag)

//獲取選中項的內容
tableView.rx.modelSelected(String.self).subscribe(onNext: { item in
print("選中項的標題為:\(item)")
}).disposed(by: disposeBag)

如果需要再block裡調用self方法,在 in 前面的 變量前加上 [weak self] :

tableView.rx.itemSelected.subscribe(onNext: { [weak self] indexPath in

self?.showMessage("選中項的indexPath為:\(indexPath)")

}).disposed(by: disposeBag)

cell取消選中事件

//獲取被取消選中項的索引
tableView.rx.itemDeselected.subscribe(onNext: { [weak self] indexPath in
self?.showMessage("被取消選中項的indexPath為:\(indexPath)")

}).disposed(by: disposeBag)

//獲取被取消選中項的內容
tableView.rx.modelDeselected(String.self).subscribe(onNext: {[weak self] item in
self?.showMessage("被取消選中項的的標題為:\(item)")
}).disposed(by: disposeBag)

cell將要顯示出來的事件

//獲取選中項的索引
tableView.rx.willDisplayCell.subscribe(onNext: { cell, indexPath in
print("將要顯示單元格indexPath為:\(indexPath)")
print("將要顯示單元格cell為:\(cell)\n")

}).disposed(by: disposeBag)

RxDataSources

RxDataSource 的本質就是使用 RxSwift 對 UITableView 和 UICollectionView 的數據源做了一層包裝。使用它可以大大減少我們的工作量。

如果我們的 tableview 需要顯示多個 section、或者更加複雜的編輯功能時,可以藉助 RxDataSource 這個第三方庫幫我們完成。

引入項目:

CocoaPods:
pod 'RxDataSources', '~> 3.0'
Carthage:
github "RxSwiftCommunity/RxDataSources" ~> 3.0

RxDataSources 是以 section 來做為數據結構的。所以不管我們的 tableView是單分區還是多分區,在使用 RxDataSources 的過程中,都需要返回一個 section 的數組。

我們要顯示下面的內容:

iOS開發必會技能 - RxSwift 系列四、UITableView的使用

單分區的 TableView

一:使用自帶的Section

import UIKit
import RxSwift
import RxCocoa
import RxDataSources

class ViewController: UIViewController {
var tableView:UITableView!
let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

//創建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創建一個重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)

//初始化數據
let items = Observable.just([
SectionModel(model: "", items: [
"UILable的用法",
"UIText的用法",
"UIButton的用法"
])
])

//創建數據源
let dataSource = RxTableViewSectionedReloadDataSource
<sectionmodel>>(configureCell: {
(dataSource, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(indexPath.row):\(element)"
return cell
})

//綁定單元格數據
items.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}
/<sectionmodel>

二:使用自定義的Section

import UIKit
import RxSwift
import RxCocoa
import RxDataSources

class ViewController: UIViewController {

var tableView:UITableView!
let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

//創建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創建一個重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)

//初始化數據
let sections = Observable.just([
MySection(header: "", items: [
"UILable的用法",
"UIText的用法",
"UIButton的用法"
])
])

//創建數據源
let dataSource = RxTableViewSectionedAnimatedDataSource<mysection>(
//設置單元格
configureCell: { ds, tv, ip, item in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")
?? UITableViewCell(style: .default, reuseIdentifier: "Cell")

cell.textLabel?.text = "\(ip.row):\(item)"

return cell
})

//綁定單元格數據
sections.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}

//自定義Section
struct MySection {
var header: String
var items: [Item]
}

extension MySection : AnimatableSectionModelType {
typealias Item = String

var identity: String {
return header
}

init(original: MySection, items: [Item]) {
self = original
self.items = items
}
}
/<mysection>

多分區的UITableView

一:使用自帶的Section

import UIKit
import RxSwift
import RxCocoa
import RxDataSources

class ViewController: UIViewController {

var tableView:UITableView!

let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

//創建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創建一個重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)

//初始化數據
let items = Observable.just([
SectionModel(model: "基本控件", items: [
"UILable的用法",
"UIText的用法",
"UIButton的用法"
]),
SectionModel(model: "高級控件", items: [
"UITableView的用法",
"UICollectionViews的用法"
])
])

//創建數據源
let dataSource = RxTableViewSectionedReloadDataSource
<sectionmodel>>(configureCell: {
(dataSource, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(indexPath.row):\(element)"
return cell
})

//設置分區頭標題
dataSource.titleForHeaderInSection = { ds, index in
return ds.sectionModels[index].model
}

//設置分區尾標題
//dataSource.titleForFooterInSection = { ds, index in
// return "footer"
//}

//綁定單元格數據

items
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}
/<sectionmodel>

二:使用自定義的Section

import UIKit
import RxSwift
import RxCocoa
import RxDataSources

class ViewController: UIViewController {

var tableView:UITableView!

let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

//創建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創建一個重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)

//初始化數據
let sections = Observable.just([
MySection(header: "基本控件", items: [
"UILable的用法",
"UIText的用法",
"UIButton的用法"
]),
MySection(header: "高級控件", items: [
"UITableView的用法",
"UICollectionViews的用法"
])
])

//創建數據源

let dataSource = RxTableViewSectionedAnimatedDataSource<mysection>(
//設置單元格
configureCell: { ds, tv, ip, item in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")
?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = "\(ip.row):\(item)"

return cell
},
//設置分區頭標題
titleForHeaderInSection: { ds, index in
return ds.sectionModels[index].header
}
)

//綁定單元格數據
sections
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}

//自定義Section
struct MySection {
var header: String
var items: [Item]
}

extension MySection : AnimatableSectionModelType {
typealias Item = String

var identity: String {
return header
}

init(original: MySection, items: [Item]) {
self = original
self.items = items
}
}
/<mysection>
iOS開發必會技能 - RxSwift 系列四、UITableView的使用


分享到:


相關文章: