有加载状态展示的 TableViewCell
2018-05-25 本文已影响17人
LovelyYilia
git 项目地址YILTableViewManager
本库主要是针对需要cell 对应的网络数据模型分别在不同状态,但cell 需要展示出对应状态。如: 数据正在获取,cell 需要展示加载状态; 数据获取成功,cell 展示成功对应的数据;数据获取失败,cell 展示成功对应状态。
支持 cocoaPods!
本案例中 数据一共有4个状态: idle
loading
success
failure
欢迎支持 :)
效果展示
1.gif内部设计实现
uml.jpg
使用方法
import UIKit
import YILTableViewManager
func delay(_ delay:Double, closure:@escaping()->()) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: closure)
}
class TableViewController: UITableViewController {
var tableViewManager = TableViewManager()
lazy var itemOne : ModelManager = {
let manager = ModelManager("cellOne", cellReuseIdenfier: OneTableViewCell.reuseIdentifier, cellClassString: NSStringFromClass(OneTableViewCell.self))
manager.didSelect = { [weak self] (tableView, indexPath, data) in
if let strongSelf = self {
let viewController = ViewController()
if let data = data as? [String: String],
let title = data["title"] {
viewController.title = title
}
strongSelf.navigationController?.pushViewController(viewController, animated: true)
}
print("点我了")
}
return manager
}()
lazy var itemTwo : ModelManager = {
return ModelManager("cellTwo", cellReuseIdenfier: TwoTableViewCell.reuseIdentifier, cellNib: UINib(nibName: "TwoTableViewCell", bundle: nil))
}()
lazy var itemThree : ThreeModelManager = {
let manager = ThreeModelManager("cellThree", cellReuseIdenfier: ThreeTableViewCell.reuseIdentifier, cellNib: UINib(nibName: "ThreeTableViewCell", bundle: nil))
manager.myAction = {[weak self] (data, sender) in
if let strongSelf = self {
let alert = UIAlertController(title: "你点到我了!", message: "有什么需要吗?", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
strongSelf.navigationController?.present(alert, animated: true)
}
}
return manager
}()
lazy var itemFour : ModelManager = {
return ModelManager("cellFour", cellReuseIdenfier: TwoTableViewCell.reuseIdentifier, cellNib: UINib(nibName: "TwoTableViewCell", bundle: nil))
}()
override func viewDidLoad() {
super.viewDidLoad()
title = "示例"
tableView.estimatedRowHeight = 44
tableView.rowHeight = UITableViewAutomaticDimension
tableViewManager.tableView = tableView
tableViewManager.append([itemOne, itemTwo, itemFour, itemThree])
updateOneItem(itemOne)
updateTwoItem(itemTwo)
updateFourItem(itemFour)
///tableViewManager insert 测试
// delay(1) {
// self.tableViewManager.insert([self.itemFour, self.itemFive, self.itemSix], at: 4)
// self.tableViewManager.insert([self.itemFour, self.itemFive, self.itemSix], at: 2)
// self.tableViewManager.insert([self.itemFour, self.itemFive, self.itemSix], at: -1)
// self.tableView.reloadData()
// }
///tableViewManager remove 测试
// delay(1) {
// self.tableViewManager.remove(at: 1)
// self.tableView.reloadData()
// }
///tableViewManager removeSubrange 测试
// delay(1) {
// self.tableViewManager.removeSubrange(Range(uncheckedBounds: (3, 5)))
// self.tableView.reloadData()
// }
///tableViewManager remove 测试
// delay(1) {
// self.tableViewManager.remove(self.itemSix)
// self.tableView.reloadData()
// }
///tableViewManager removeAll 测试
// delay(13) {
// self.tableViewManager.removeAll()
// self.tableView.reloadData()
// }
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/// itemOne 状态更新 测试
func updateOneItem(_ item: ModelManager) {
item[.idle] = ["title": "idle", "value": "-idle value-"]
item[.loading] = ["title": "loading...", "value": "-loading value-"]
delay(1.5) {
item.viewStatus = .loading
}
delay(3) {
item[.success] = ["title": "success", "value": "-success value-"]
item.viewStatus = .success
}
}
///状态更新 测试
func updateTwoItem(_ item: ModelManager) {
item[.idle] = ["title": "idle", "image": "汽车保养", "value": "-idle value-"]
item[.loading] = ["title": "loading","image": "猜你喜欢", "value": ""]
delay(2) {
item.viewStatus = .loading
}
delay(4) {
let value = "相比 MVC,MVP在层次划分上更加清晰了,不会出现一人身兼二职的情况(有些单元测试的童鞋,会发现单元测试用例更好写了)。在此处你可以看到 View 和 Model 之间是互不知道对方存在的,这样应对变更的好处更大,很多时候都是 View 层的变化,而 Model 层发生的变化会相对较少,遵循 MVP 的结构开发后,改起来代码来也没那么蛋疼。"
item[.success] = ["title": "success", "image": "一站式服务", "value": value]
item.viewStatus = .success
}
}
///状态更新 测试
func updateFourItem(_ item: ModelManager) {
item[.idle] = ["title": "idle 状态", "image": "汽车保养", "value": "-idle value-"]
item[.loading] = ["title": "loading...","image": "猜你喜欢", "value": ""]
delay(3) {
item.viewStatus = .loading
}
delay(5) {
let value = "女孩子之所以会问一些奇奇怪怪的问题,其实只是想要自己的另一半承认自己最美最重要而已啊。你要是问“之前说过的话为什么还要反复说”,那就太单纯了。就像你为什么昨天吃过了饭今天还要吃一样,女孩子就是要不停地收到你对她的爱意,才会对感情充满安全感。"
item[.failure] = ["title": "~ failure ~", "image": "汽车美容", "value": value]
item.viewStatus = .failure
}
}
}
OneTableViewCell.swift
import UIKit
import YILTableViewManager
// MARK: - cell
class OneTableViewCell: UITableViewCell {
static let reuseIdentifier: String = NSStringFromClass(OneTableViewCell.self)
fileprivate var _modelManager: ModelManager?
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
}
}
extension OneTableViewCell: ViewStatusable {
var modelManager: ModelManager? {
get {
return _modelManager
}
set(newValue) {
_modelManager = newValue
}
}
func config(_ viewStatus : ViewStatus, data: Any?) {
self.selectionStyle = .none
var title = "未知Title"
var value = "未知value"
if let data = data as? [String: String] {
title = data["title"] ?? "没有 Title"
value = data["value"] ?? "没有 value"
} else {
// assert(false, "类型转换失败或 data 为空")
switch viewStatus {
case .idle:
title = "idle Title"
value = "idle value"
case .loading:
title = "loading Title"
value = "loading value"
case .success:
title = "success Title"
value = "success value"
case .failure:
title = "failure Title"
value = "failure value"
}
}
textLabel?.text = title
detailTextLabel?.text = value
}
}
感谢支持 :)