MVVM+RxSwift簡単な実践
7702 ワード
1、簡単な説明 MVVMを使用してmodel、viewをデカップリングし、多重化の可能性を高めるとともに、controllerの負担を極めて軽減し、ミドルウェアviewModelによってデータソースを処理し、UIをバインドし、論理イベントを処理する.このように,種々の業務が煩雑になると,各業務間のコードを完全に分離し,コードを明確にすることができる. RxSwiftを使用すると、従来のdataSource、delegateなどのエージェントメソッドを置き換えることができ、非同期Event(イベント)シーケンスの応答式プログラミングを行い、便利で速く、論理がより明確になる. コードには優れたオープンソースライブラリ:Kingfisher,SnapKitが使用されています.
2、運行効果
3、目次構造
4、ページコード
2、運行効果
3、目次構造
4、ページコード
controller
//
// MainViewController.swift
// ss
//
// Created by WES319 on 11/7/18.
// Copyright © 2018 . All rights reserved.
//
import UIKit
import RxCocoa
import RxSwift
import SnapKit
class MainViewController: UIViewController {
var tableView = MainTableView()
var tableViewModel: MainTableViewModel!
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = " "
tableViewModel = MainTableViewModel.init(target: self)
view.addSubview(tableView)
tableView.snp.makeConstraints { (make) in
make.edges.equalToSuperview()
}
}
}
Model
//
// ProductModel.swift
// ss
//
// Created by WES319 on 12/7/18.
// Copyright © 2018 . All rights reserved.
//
import UIKit
class ProductModel: NSObject {
var image: String
var title: String
var content: String
required init(image: String, title: String, content: String) {
self.image = image
self.title = title
self.content = content
super.init()
}
}
View
//
// MainTableView.swift
// ss
//
// Created by WES319 on 11/7/18.
// Copyright © 2018 . All rights reserved.
//
import UIKit
class MainTableView: UITableView {
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame: frame, style: style)
self.tableFooterView = UIView()
self.estimatedRowHeight = 100
self.register(MainTableViewCell.self, forCellReuseIdentifier: MainTableViewCell.cellID)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// MainTableViewCell.swift
// ss
//
// Created by WES319 on 11/7/18.
// Copyright © 2018 . All rights reserved.
//
import UIKit
import Kingfisher
class MainTableViewCell: UITableViewCell {
static let cellID = NSStringFromClass(MainTableViewCell.self)
var mainImageView = UIImageView()
var titleLabel = UILabel()
var contentLabel = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.separatorInset = UIEdgeInsetsMake(0, 15, 0, 0)
contentView.addSubview(mainImageView)
mainImageView.snp.makeConstraints { (make) in
make.top.left.bottom.equalToSuperview().inset(15)
make.height.equalTo(80).priority(999)
make.width.equalTo(mainImageView.snp.height).multipliedBy(16.0/9.0)
}
titleLabel.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.black)
contentView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { (make) in
make.left.equalTo(mainImageView.snp.right).offset(10)
make.top.equalTo(mainImageView)
make.right.lessThanOrEqualToSuperview().inset(10)
}
contentLabel.textColor = UIColor.gray
contentLabel.font = UIFont.systemFont(ofSize: 13, weight: UIFont.Weight.light)
contentLabel.numberOfLines = 2
contentView.addSubview(contentLabel)
contentLabel.snp.makeConstraints { (make) in
make.left.equalTo(titleLabel)
make.top.equalTo(titleLabel.snp.bottom).offset(5)
make.right.lessThanOrEqualToSuperview().inset(15)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(image: String, title: String, content: String) {
mainImageView.kf.setImage(with: URL.init(string: image))
titleLabel.text = title
contentLabel.text = content
}
}
ViewModel
//
// MainTableViewModel.swift
// ss
//
// Created by WES319 on 11/7/18.
// Copyright © 2018 . All rights reserved.
//
import UIKit
import RxSwift
class MainTableViewModel: NSObject {
var dataSource = Observable.just([ProductModel.init(image: "http://pic1.win4000.com/wallpaper/d/5279ae86ae5a6.jpg", title: " ", content: " , , 。 , 。 , 。 。 , 、 , , 。 , 、 、 , 。")
,ProductModel.init(image: "http://pic1.win4000.com/wallpaper/d/5279ae86ae5a6.jpg", title: " ", content: " , , 。 , 。 , 。 。 , 、 , , 。 , 、 、 , 。"),ProductModel.init(image: "http://pic1.win4000.com/wallpaper/d/5279ae86ae5a6.jpg", title: " ", content: " , , 。 , 。 , 。 。 , 、 , , 。 , 、 、 , 。"),ProductModel.init(image: "http://pic1.win4000.com/wallpaper/d/5279ae86ae5a6.jpg", title: " ", content: " , , 。 , 。 , 。 。 , 、 , , 。 , 、 、 , 。"),ProductModel.init(image: "http://pic1.win4000.com/wallpaper/d/5279ae86ae5a6.jpg", title: " ", content: " , , 。 , 。 , 。 。 , 、 , , 。 , 、 、 , 。"),ProductModel.init(image: "http://pic1.win4000.com/wallpaper/d/5279ae86ae5a6.jpg", title: " ", content: " , , 。 , 。 , 。 。 , 、 , , 。 , 、 、 , 。"),ProductModel.init(image: "http://pic1.win4000.com/wallpaper/d/5279ae86ae5a6.jpg", title: " ", content: " , , 。 , 。 , 。 。 , 、 , , 。 , 、 、 , 。")])
weak var target: MainViewController!
let disposeBag = DisposeBag()
required init(target: MainViewController) {
self.target = target
super.init()
//
self.dataSource.bind(to: target.tableView.rx.items(cellIdentifier: MainTableViewCell.cellID)) { (_, model, cell: MainTableViewCell) in
cell.update(image: model.image, title: model.title, content: model.content)
}.disposed(by: disposeBag)
// tableView
self.target.tableView.rx.modelSelected(ProductModel.self).subscribe(onNext: { (model) in
print(model.title)
}).disposed(by: disposeBag)
self.target.tableView.rx.itemSelected.subscribe(onNext: { (indexPath) in
print(indexPath.row)
self.target.tableView.deselectRow(at: indexPath, animated: true)
}).disposed(by: disposeBag)
}
}