怎樣做百度網(wǎng)站推廣青島seo關(guān)鍵詞優(yōu)化公司
文章目錄
- RxSwift - 實(shí)現(xiàn)一個MVVM架構(gòu)的TableView
- 前沿
- MVVM架構(gòu)的Tableview
- 目錄結(jié)構(gòu)
- 1、模型(Model)
- 2、視圖模型(ViewModel)
- 3、視圖(View)
- 界面效果
RxSwift - 實(shí)現(xiàn)一個MVVM架構(gòu)的TableView
前沿
MVVM
架構(gòu)在在實(shí)際開發(fā)中被廣泛應(yīng)用,它讓代碼結(jié)構(gòu)清晰美觀,易于閱讀維護(hù),同時也彌補(bǔ)了MVC
結(jié)構(gòu)中Controller
臃腫的問題
今天來實(shí)現(xiàn)一個基于RxSwift
的基礎(chǔ)TableView
頁面
效果:使用
RxSwift
,將View
與Model
進(jìn)行綁定,實(shí)現(xiàn)動態(tài)修改數(shù)據(jù)時更新UI
MVVM架構(gòu)的Tableview
目錄結(jié)構(gòu)
以下是目錄結(jié)構(gòu)
目錄由ViewModel
、View
、Model
三個文件夾組成
1、模型(Model)
在Model
文件夾下新建Product
文件
import Foundationstruct Product {let imgName: String // 圖let name: String// 名稱let price: String// 價格
}
模型簡單表示了一個商品的
2、視圖模型(ViewModel)
在ViewModel
文件夾下新建ProductViewModel
文件。它相當(dāng)于是View
和Model
的橋梁,在ViewModel
中會有相應(yīng)的獲取數(shù)據(jù)以及處理數(shù)據(jù)的方法,然后將數(shù)據(jù)傳輸?shù)?code>View
import Foundation
import RxSwiftclass ProductViewModel {// PublishSubject: 只會發(fā)送新的事件給訂閱者,訂閱之前的事件不會發(fā)送// BehaviorSubject: 會保持最新的值,并將其發(fā)送給新的訂閱者let items = PublishSubject<[Product]>()
// let items = BehaviorSubject<[Product]>(value: [])var productArray: [Product]!func fetchProductList() {// 在這里可以做網(wǎng)絡(luò)請求// 咱們就直接用假數(shù)據(jù)productArray = [Product(imgName: "apple", name: "apple", price: "10"),Product(imgName: "banana", name: "banana", price: "5"),Product(imgName: "pear", name: "pear", price: "4"),Product(imgName: "watermelon", name: "watermelon", price: "3"),Product(imgName: "mango", name: "mango", price: "8")]items.onNext(productArray)
// items.onCompleted()}func addData() {productArray.append(Product(imgName: "peach", name: "peach", price: "7"))items.onNext(productArray)}
}
該類中:
- 定義了時間發(fā)布者
items
,使用PublishSubject
類型 - 定義獲取數(shù)據(jù)的方法
fetchProductList()
,獲取完數(shù)據(jù)后,使用onNext
將事件發(fā)布出去。代碼中注釋掉onCompleted()
,是因?yàn)橄胍獙?shí)現(xiàn)后續(xù)數(shù)據(jù)更新的操作,onCompleted
會終止序列,使其不再接收新的元素。 - 定義
addData()
方法,界面中將通過點(diǎn)擊按鈕
模擬增加數(shù)據(jù)操作
3、視圖(View)
在View
層,首先有個簡單的CellProductTableViewCell
,它有一個數(shù)據(jù)有屬性item
,賦值時進(jìn)行UI內(nèi)容樣式設(shè)置
import UIKitclass ProductTableViewCell: UITableViewCell {var item: Product? = nil {didSet{textLabel?.text = item?.name}}override func awakeFromNib() {super.awakeFromNib()// Initialization code}override func setSelected(_ selected: Bool, animated: Bool) {super.setSelected(selected, animated: animated)// Configure the view for the selected state}}
接下來是ViewController
import UIKit
import RxSwift
import RxCocoaclass ViewController: UIViewController, UIScrollViewDelegate {private let bag = DisposeBag()private let viewModel = ProductViewModel()lazy var tableView: UITableView = {let tableView = UITableView(frame: view.bounds, style: UITableView.Style.grouped)view.addSubview(tableView)return tableView}()override func viewDidLoad() {super.viewDidLoad()tableView.rx.setDelegate(self).disposed(by: bag)bindTableView()let btn:UIButton = UIButton(type: .system)btn.frame = CGRectMake(10, view.frame.size.height - 80, view.frame.size.width - 20, 50)btn.backgroundColor = .lightGraybtn.setTitle("addData", for: UIControl.State.normal)btn.rx.tap.subscribe(onNext: { [unowned self] inself.viewModel.addData()}).disposed(by: bag)view.addSubview(btn)}private func bindTableView() {tableView.register(ProductTableViewCell.self, forCellReuseIdentifier: "cellId")viewModel.items.bind(to: tableView.rx.items(cellIdentifier: "cellId", cellType: ProductTableViewCell.self)) { (row,item,cell) incell.item = item}.disposed(by: bag)tableView.rx.modelSelected(Product.self).subscribe(onNext: { item inprint("SelectedItem: \(item.name)")}).disposed(by: bag)viewModel.fetchProductList()}
}
- 定義
private let bag = DisposeBag()
,作用就是在合適的時機(jī)自動調(diào)用這些 Disposable 對象的 dispose() 方法,釋放資源,避免內(nèi)存泄漏 - 持有
ViewModel
:private let viewModel = ProductViewModel()
- 初始化
tableView
viewDidLoad()
中,指定了tableView
代理為self
,然后將viewModel
的items
事件綁定到tableView
,即將數(shù)據(jù)源
綁定到表視圖行
。同時訂閱了選中某個模型的事件modelSelected
,即選中某個Cell的事件。(使用RxCocoa
提供的方法實(shí)現(xiàn))- 增加一個按鈕,點(diǎn)擊時調(diào)用
viewModel.addData()
方法,動態(tài)修改數(shù)據(jù)源。因?yàn)橐褜?code>tableView綁定到數(shù)據(jù)源,視圖也將動態(tài)刷新
界面效果
@oubijiexi