下拉刷新仍然使用MJRefresh,为了不每一次下拉刷新都写两个方式且重复的数据处理逻辑,给UIScrollView添加一个分类,使用运行时绑定pageNo和pageSize,废话不多说直接上代码
import UIKit
import MJRefresh
extension UIScrollView {
struct runtimeKey {
static var pageNoKey = UnsafeRawPointer.init(bitPattern: "pageNoKey".hashValue)
static var pageSizeKey = UnsafeRawPointer.init(bitPattern: "pageSizeKey".hashValue)
static var dataSourceKey = UnsafeRawPointer.init(bitPattern: "dataSourceKey".hashValue)
}
var pageNo:Int? {
set{
objc_setAssociatedObject(self, UIScrollView.runtimeKey.pageNoKey!, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
}
get {
return objc_getAssociatedObject(self, UIScrollView.runtimeKey.pageNoKey!) as? Int
}
}
var pageSize:Int? {
set{
objc_setAssociatedObject(self, UIScrollView.runtimeKey.pageSizeKey!, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
}
get {
return objc_getAssociatedObject(self, UIScrollView.runtimeKey.pageSizeKey!) as? Int
}
}
var refreshDataSource:Array? {
set{
objc_setAssociatedObject(self, UIScrollView.runtimeKey.dataSourceKey!, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
get {
return objc_getAssociatedObject(self, UIScrollView.runtimeKey.dataSourceKey!) as? Array
}
}
var uHead: MJRefreshHeader {
get { return (mj_header ?? MJRefreshHeader.init())! }
set { mj_header = newValue }
}
var uFoot: MJRefreshFooter {
get { return (mj_footer ?? MJRefreshFooter.init())! }
set { mj_footer = newValue }
}
func lf_addHeader(beginRefresh:Bool, block:@escaping LFCallBack){
self.pageSize = 10
self.pageNo = 1
self.uHead = URefreshHeader{[unowned self] in
self.pageNo = 1
block()
}
if beginRefresh {
self.uHead.beginRefreshing()
}
}
func lf_addFooter(block:@escaping LFCallBack){
self.uFoot = URefreshFooter{[unowned self] in
self.pageNo! += 1
block()
}
}
func lf_setRefresh(dataSource:Array?){
if self.pageNo == 1 {
self.refreshDataSource = dataSource
}else {
self.refreshDataSource? += dataSource ?? []
}
if self.refreshDataSource?.count == 0 {
self.ly_showEmpty()
}else {
self.ly_hideEmpty()
}
self.uHead.endRefreshing()
if dataSource?.count == 0 && dataSource?.count ?? 0 < self.pageSize ?? 10 {
self.uFoot.endRefreshingWithNoMoreData()
}else {
self.uFoot.endRefreshing()
}
}
}
class URefreshHeader: MJRefreshGifHeader {
override func prepare() {
super.prepare()
lastUpdatedTimeLabel?.isHidden = true
stateLabel?.isHidden = true
}
}
class URefreshAutoHeader: MJRefreshHeader {}
class URefreshFooter: MJRefreshBackNormalFooter {}
class URefreshAutoFooter: MJRefreshAutoFooter {}
class URefreshDiscoverFooter: MJRefreshBackGifFooter {
override func prepare() {
super.prepare()
// backgroundColor = UIColor.init(red: 239/255.0, green: 239/255.0, blue: 239/255.0, alpha: 1)
backgroundColor = UIColor.clear
setImages([UIImage(named: "pullToRefresh_0_80x60_")!], for: .idle)
stateLabel?.isHidden = true
refreshingBlock = { self.endRefreshing() }
}
}
class URefreshTipKissFooter: MJRefreshBackFooter {
lazy var tipLabel: UILabel = {
let tl = UILabel()
tl.textAlignment = .center
tl.textColor = UIColor.lightGray
tl.font = UIFont.systemFont(ofSize: 14)
tl.numberOfLines = 0
return tl
}()
lazy var imageView: UIImageView = {
let iw = UIImageView()
iw.image = UIImage(named: "pullToRefresh_0_80x60_")
return iw
}()
override func prepare() {
super.prepare()
// backgroundColor = UIColor.init(red: 239/255.0, green: 239/255.0, blue: 239/255.0, alpha: 1)
backgroundColor = UIColor.clear
mj_h = 240
addSubview(tipLabel)
addSubview(imageView)
}
override func placeSubviews() {
tipLabel.frame = CGRect(x: 0, y: 40, width: bounds.width, height: 60)
imageView.frame = CGRect(x: (bounds.width - 80 ) / 2, y: 110, width: 80, height: 80)
}
convenience init(with tip: String) {
self.init()
refreshingBlock = { self.endRefreshing() }
tipLabel.text = tip
}
}
以上核心代码主要看lf_setRefresh这个方式,包含了数据源处理和空白图的处理
具体使用方式:在控制器中添加两行
tableView.lf_addHeader(beginRefresh: true) {[unowned self] in
self.loadData()
}
tableView.lf_addFooter {[unowned self] in
self.loadData()
}
还没完,需要在loadData方式设置一下数据源,调用lf_setRefresh方式
func loadData() {
HttpRequest.loadData(target: PXSArticleAPI.articleList(page: tableView.pageNo ?? 1, cate: self.cateId ?? 0,title:searchStr ?? ""), success: { (res) in
let json = JSON(res)
let article_list = JSONDeserializer.deserializeModelArrayFrom(json: json["data"]["result"]["article_list"].description)
// self.mdataSource = article_list as! Array
self.tableView.lf_setRefresh(dataSource: article_list as?[PXSArticleListModel])
self.tableView.reloadData()
}) { (state_code, message) in
self.tableView.uHead.endRefreshing()
self.tableView.uFoot.endRefreshing()
}
}
到这儿所以逻辑都完成了,执行给tableView设置数据源的时侯通过self.tableView.refreshDataSource?.count获取处理后的数据源
override func numberOfSections(in tableView: UITableView) -> Int {
return self.tableView.refreshDataSource?.count ?? 0
}
写的不好勿喷