pod 'Cartography' # swift 布局
pod 'RxSwift'
pod 'RxCocoa'
pod 'HandyJSON', '5.0.0-beta'
升级xcode到10.2之后,swift编译版本为5.0。
在引入HandyJSON 的时候,默认是4.2.1版本,报错了:Undefined symbols for architecture x86_64:
“_swift_getFieldAt”。解决办法是使用5.0.0-beta版本就可以了。
view controller: 里边新建一个tableview,然后和viewmodel的dataSourceObservable和tableview绑定。
import UIKit
import Cartography
class MVVMViewController: UIViewController {
let viewModel = MVVMViewModel() // view 层持有 viewModel
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "天行数据"
view.addSubview(tableView)
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 112
tableView.register(MVVMTableViewCell.self, forCellReuseIdentifier: "cell")
constrain(view, tableView) { (view, tableView) in
tableView.edges == view.edges
}
viewModel.dataSourceObservable.bind(to: tableView.rx.items(cellIdentifier: "cell")) {
(_ , dd, cell) in
let cell = cell as! MVVMTableViewCell
cell.configData(model: dd)
}.disposed(by: viewModel.disposeBag)
}
}
viewmodel init方法里用URLSession.shared.rx.json生成一个Observable 对象,数据使用 天行数据 的api 接口,并把json使用HandyJSON转换为模型。
import UIKit
import RxSwift
import HandyJSON
class MVVMViewModel {
let dataSourceObservable :Observable<[MVVMModel]>
let disposeBag = DisposeBag()
init() {
let urlStr = "https://api.tianapi.com/meinv/?key=20dd4620e06b0e108d3e081bb981f710&num=20"
let url = URL(string: urlStr)
let request = URLRequest(url: url!)
dataSourceObservable = URLSession.shared.rx.json(request: request).map { (result) -> [MVVMModel] in
if let data = result as? [String: Any],
let channels = data["newslist"] as? [[String: Any]] {
let tmparr = [MVVMModel].deserialize(from: channels)
return tmparr as! [MVVMModel]
}else {
return []
}
}
}
}
cell 使用Cartography 进行布局
import UIKit
import Cartography
class MVVMTableViewCell: UITableViewCell {
let img = UIImageView()
let titleLabel = UILabel()
let subtitleLabel = UILabel()
let timeLabel = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(img)
contentView.addSubview(titleLabel)
contentView.addSubview(subtitleLabel)
contentView.addSubview(timeLabel)
img.contentMode = UIView.ContentMode.scaleAspectFit
constrain(contentView,img) { (contentView, img) in
img.left == contentView.left + 16
img.top == contentView.top + 16
img.width == 80
img.height == 80
}
constrain(contentView, titleLabel, img) { (contentView,titleLabel,img) in
titleLabel.left == img.right + 8
titleLabel.top == img.top
titleLabel.width == UIScreen.main.bounds.size.width - 120
}
constrain(subtitleLabel, titleLabel) { (subtitleLabel,titleLabel) in
subtitleLabel.left == titleLabel.left
subtitleLabel.top == titleLabel.bottom + 8
subtitleLabel.width == titleLabel.width
}
constrain(img,timeLabel,titleLabel,contentView) { (img,timeLabel,titleLabel,contentView) in
timeLabel.left == titleLabel.left
timeLabel.bottom == img.bottom
timeLabel.width == titleLabel.width
timeLabel.bottom == contentView.bottom - 16
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
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
}
func configData(model: MVVMModel) {
img.setImageWith(URL(string: model.picUrl!), placeholder: nil)
titleLabel.text = model.title
timeLabel.text = model.ctime
subtitleLabel.text = model.description
}
}
model 比较简单
import UIKit
import HandyJSON
class MVVMModel : HandyJSON {
let title: String? = nil
let ctime: String? = nil
let picUrl: String? = nil
let url: String? = nil
let description: String? = nil;
required init() {}
}
源码地址:https://github.com/hxcshr/awesome_ios_test