//
// MyTableView.swift
// swjmanager
//
// Created by Jo on 2017/11/22.
// Copyright © 2017年 swj. All rights reserved.
// 使用该组件请注意,在控制器中用MyTableViewDelegate替代UITableViewDelegate
import UIKit
enum MyTableViewSetting {
//上拉加载更多的view的高度
static let MyTableViewSetting_FooterView_Height: CGFloat = 80
//上拉加载limit:超过就加载
static let MyTableViewSetting_FooterView_Loading_limit: CGFloat = 60
static let MyTableViewSetting_FooterView_Idle_Text = "上拉加载更多"
static let MyTableViewSetting_FooterView_Release_Text = "松开开始加载"
static let MyTableViewSetting_FooterView_Loading_Text = "正在加载"
}
@objc protocol MyTableViewDelegate: NSObjectProtocol {
@objc optional func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
@objc optional func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
@objc optional func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
@objc optional func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
@objc optional func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
//上拉加载更多触发
@objc optional func tableViewLoadingMore()
//刷新的时候触发,必须重写
func tableViewRefreshing()
@objc optional func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
}
extension MyTableView: UITableViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard contentSize.height >= bounds.height else {
label_footer.isHidden = true
return
}
guard contentInset.bottom <= 0 && isLoadMore == false else {
return
}
//上拉加载逻辑
if let myDelegate = myDelegate {
if myDelegate.responds(to: #selector(myDelegate.tableViewLoadingMore)) {
label_footer.isHidden = false
//上拉超过限定大小
if scrollView.contentOffset.y + bounds.height - contentSize.height > MyTableViewSetting.MyTableViewSetting_FooterView_Loading_limit {
label_footer.text = MyTableViewSetting.MyTableViewSetting_FooterView_Release_Text
isLoadMore = true
} else {
label_footer.text = MyTableViewSetting.MyTableViewSetting_FooterView_Idle_Text
}
}
}
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
//下拉刷新逻辑
if scrollView.contentOffset.y <= -MyTableView_Refreshing_limit {
myRefreshControl.beginRefreshing()
showLoadingView()
} else {
if myRefreshControl.isRefreshing == true {
endRefreshing()
}
}
guard contentInset.bottom <= 0 else {
return
}
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
//上拉加载
if isLoadMore == true {
bounces = false
loadingMore()
} else {
bounces = true
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if let myDelegate = myDelegate {
if myDelegate.responds(to: #selector(myDelegate.tableView(_:heightForRowAt:))) {
return myDelegate.tableView!(tableView, heightForRowAt: indexPath)
}
}
return 60
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if let myDelegate = myDelegate {
if myDelegate.responds(to: #selector(tableView(_:heightForHeaderInSection:))) {
return myDelegate.tableView!(tableView, heightForHeaderInSection: section)
}
}
return 0
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if let myDelegate = myDelegate {
if myDelegate.responds(to: #selector(tableView(_:viewForFooterInSection:))) {
return myDelegate.tableView!(tableView, viewForFooterInSection: section)
}
}
return nil
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let myDelegate = myDelegate {
if myDelegate.responds(to: #selector(tableView(_:viewForHeaderInSection:))) {
return myDelegate.tableView!(tableView, viewForHeaderInSection: section)
}
}
return nil
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
if let myDelegate = myDelegate {
if myDelegate.responds(to: #selector(tableView(_:heightForFooterInSection:))) {
return myDelegate.tableView!(tableView , heightForFooterInSection: section)
}
}
return 0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let myDelegate = myDelegate {
if myDelegate.responds(to: #selector(myDelegate.tableView(_:didSelectRowAt:))) {
myDelegate.tableView!(tableView, didSelectRowAt: indexPath)
}
}
}
}
class MyTableView: UITableView {
var isLoadMore: Bool = false
var label_footer = UILabel.init()
let myRefreshControl = UIRefreshControl.init()
let pullView_Content = UIImageView.init()
//刷新时候的图案控件
let pullView_Logo = UIImageView.init(frame: CGRect.init(x: 0, y: 0, width: MyTableView_PullView_Logo_Size.height, height: MyTableView_PullView_Logo_Size.height))
weak var myDelegate: MyTableViewDelegate?
//存放要刷新过程时候显示的动画的图片,下拉加载时候的动画
lazy var loadingImages: [UIImage] = {
var array: [UIImage] = []
for i in 1 ... 10 {
let image = UIImage.init(named: "xiala_anima_progress_\(i)")
array.append(image!)
}
return array
}()
override func awakeFromNib() {
super.awakeFromNib()
initRefreshControl()
addRefreshViewForPull()
initTB()
}
func initRefreshControl() {
myRefreshControl.backgroundColor = UIColor.clear
myRefreshControl.tintColor = UIColor.clear
addSubview(myRefreshControl)
addFootView()
}
//添加下拉加载
func addFootView() {
label_footer = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: bounds.width, height: MyTableViewSetting.MyTableViewSetting_FooterView_Height))
label_footer.backgroundColor = UIColor.clear
label_footer.textColor = UIColor.black
label_footer.textAlignment = .center
label_footer.isHidden = true
label_footer.text = MyTableViewSetting.MyTableViewSetting_FooterView_Idle_Text
addSubview(label_footer)
}
override func layoutSubviews() {
super.layoutSubviews()
label_footer.center = CGPoint.init(x: bounds.width / 2, y: contentSize.height + MyTableViewSetting.MyTableViewSetting_FooterView_Height / 2.00)
}
func initTB() {
separatorStyle = .none
delegate = self
}
//下拉时候的显示图案
func addRefreshViewForPull() {
pullView_Content.frame = CGRect.init(x: 0, y: -myRefreshControl.frame.height, width: Screen_Size.width, height: myRefreshControl.frame.height)
pullView_Content.backgroundColor = MyTableView_RefreshView_PullView_BGColor
addSubview(pullView_Content)
pullView_Logo.image = MyTableView_RefreshView_Pull_Image
pullView_Logo.center = CGPoint.init(x: pullView_Content.center.x, y: 20)
pullView_Content.addSubview(pullView_Logo)
}
fileprivate func showLoadingView() {
if !pullView_Logo.isAnimating {
pullView_Logo.animationImages = loadingImages
pullView_Logo.animationRepeatCount = 0
pullView_Logo.animationDuration = 1
pullView_Logo.startAnimating()
if let myDelegate = myDelegate {
myDelegate.tableViewRefreshing()
}
}
}
//结束刷新
func endRefreshing() {
myRefreshControl.endRefreshing()
pullView_Logo.stopAnimating()
}
//开始加载更定
func loadingMore() {
contentInset.bottom = MyTableViewSetting.MyTableViewSetting_FooterView_Height
label_footer.text = MyTableViewSetting.MyTableViewSetting_FooterView_Loading_Text
if let myDelegate = myDelegate {
if myDelegate.responds(to: #selector(myDelegate.tableViewLoadingMore)) {
return myDelegate.tableViewLoadingMore!()
}
}
}
//结束加载更多
func endLoadingMore() {
contentInset.bottom = 0
isLoadMore = false
bounces = true
}
}
使用:
//
// TodayMatchViewController.swift
// LSJ
//
// Created by Jo on 2017/12/11.
// Copyright © 2017年 yibu. All rights reserved.
//
import UIKit
extension TodayMatchViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: OnlineGameVC_TB_Identifier) as? MatchCell
if cell == nil {
cell = Bundle.main.loadNibNamed("MatchCell", owner: nil, options: nil)?.last as? MatchCell
cell?.selectionStyle = .none
}
if indexPath.row < 5 {
cell?.updateUI(withModel: MatchModel.getVirtualModel(isJoin: true))
} else {
cell?.updateUI(withModel: MatchModel.getVirtualModel(isJoin: false))
}
return cell!
}
}
extension TodayMatchViewController: MyTableViewDelegate {
func tableViewLoadingMore() {
printLog(message: "上拉机制")
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return MatchTBHeaderView_Frame.height
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return nil
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let model = MatchModel.getVirtualModel(isJoin: true)
let headeView = MatchTBHeaderView.init(withDay: model.match_begin_day!, date: getDateString(fromDate: model.match_begin_date!))
return headeView
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
printLog(message: "点击了")
self.tb_match.endRefreshing()
self.tb_match.endLoadingMore()
let sb = UIStoryboard.init(name: "JoinGameViewController", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "JoinGameViewController")
//push的控制器隐藏底部工具栏
vc.hidesBottomBarWhenPushed = true
navigationController?.pushViewController(vc, animated: true)
}
func tableViewRefreshing() {
printLog(message: "开始刷新")
}
}
class TodayMatchViewController: BaseViewController {
@IBOutlet weak var tb_match: MyTableView!
override func viewDidLoad() {
super.viewDidLoad()
tb_match.myDelegate = self
tb_match.dataSource = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}