1. 什么是RxDataSources
RxDataSources是RxSwiftCommunity专门为UITableView和UICollectionView开发的数据源. 也就是说,在使用RxSwift的时候, 最好使用RxDataSources而不是TableView和CollectionView的代理协议和数据源. 这样才符合Reactive编程的思想
具体为啥使用 官方GITHUB上写的很清楚了
Writing table and collection view data sources is tedious. There is a large number of delegate methods that need to be implemented for the simplest case possible.
2. 符合MVVM思想的代码
2.1 MVVM思想大概的意思

这是从 raywenderlich 出的 RxSwift Reactive Programming with Swift 上截的图.
书上第355页上有具体的规则
MVVM follows these simple rules:
• Models don’t talk directly to other classes, although they can emit notifications about data changes.
• View Models talk to Models and expose data to the View Controllers.
• View Controllers only talk to View Models and Views as they handle view
lifecycle and bind data to UI components.
• Views only notify view controllers about events (just as with MVC).
2.2 根据规则, 创建swift文件
- ViewModel.swift
说明: - BottomCell.swift
说明: - 以及已有的ViewController.swift
说明:
3 各部分实现代码
3.1 ViewModel.swift
import Foundation
import RxDataSources
import RxSwift
//每个CELL里面要展示的数据定义
struct CustomData{
var imageName: String
var imageLabel: String
}
//定义Section的数据结构,包含一个header和CustomData里面的数据
struct SectionOfCustomData{
var header: String
var items: [Item]
}
extension SectionOfCustomData: SectionModelType {
typealias Item = CustomData
init(original: SectionOfCustomData, items: [Item]) {
self = original
self.items = items
}
}
//MARK: 为数据结构设置数据源和数据(设想,数据来自于Realm数据库)
//设置数据源
let dataSource = RxCollectionViewSectionedReloadDataSource<SectionOfCustomData>()
//这里设置了数据
/*
let data = Variable([
AnimatedSectionModel(title: "Section: 0", data: ["0-0-1", "0-0-2", "0-0-3", "0-0-4", "0-1-1", "0-1-2", "0-1-3", "0-1-4","0-3-1", "0-3-2", "0-3-3", "0-3-4"], imageArray: ["Building", "Hospital", "House", "Small_School", "Supermarket"])
])
*/
let data = Variable([
SectionOfCustomData(header: "Test Header Test",
items: [
CustomData(imageName: "Building", imageLabel: "Building测试"),
CustomData(imageName: "House", imageLabel: "House测试"),
CustomData(imageName: "House", imageLabel: "House测试"),
CustomData(imageName: "House", imageLabel: "House测试"),
CustomData(imageName: "House", imageLabel: "House测试"),
CustomData(imageName: "House", imageLabel: "House测试")
]
)
])
3.2 BottomCell.swift
import UIKit
class BottomCell: UICollectionViewCell {
//定义准备放入CELL的控件
var contentLabel: UILabel!
var contentImage: UIImageView!
//不用xib或者storyboard的话需要重写init属性
override init(frame: CGRect) {
super.init(frame: frame)
//调用initView函数
initView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func initView(){
//设置CELL内部空间的属性
contentImage = UIImageView(frame: CGRect(x: 0, y: 0, width: screenWidth/4, height: screenWidth/4))
contentLabel = UILabel(frame: CGRect(x: 0, y: 0, width: screenWidth/4, height: screenWidth/4))
/*
titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: screenWidth/5, height: 10))
*/
//把设置好的控件添加到BottomCell中
self.addSubview(contentImage)
self.addSubview(contentLabel)
}
}
3.3 ViewController 中设置
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
class ViewController: UIViewController {
//声明一个UICollectionView
var bottomCollectionView: UICollectionView?
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
print(screenHeight)
print(screenWidth)
//调用添加bottomCollectionView函数,把其添加到view中
addBottomCollectionView()
//为bottomCollectionView具体设置数据
dataSource.configureCell = { _, bottomCollectionView, IndexPath, data
in
let cell = bottomCollectionView.dequeueReusableCell(withReuseIdentifier: "BottomCell", for: IndexPath) as! BottomCell
cell.contentImage.image = UIImage(named: data.imageName)
cell.contentLabel.text = data.imageLabel
return cell
}
//把数据绑定给collectionView
data.asDriver()
.drive(bottomCollectionView!.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag)
}
//MARK: 底部的bottomCollectionView
func addBottomCollectionView() {
let layout = UICollectionViewFlowLayout()
bottomCollectionView = UICollectionView(frame: CGRect(x:0, y:screenHeight/2, width: screenWidth, height: screenHeight/2), collectionViewLayout: layout)
bottomCollectionView?.register(BottomCell.self, forCellWithReuseIdentifier: "BottomCell")
bottomCollectionView?.backgroundColor = UIColor.white
//设置每一个CELL的宽高
layout.itemSize = CGSize(width: screenWidth/4, height: screenWidth/4)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
self.view.addSubview(bottomCollectionView!)
}
}
网友评论