自定义tableview实现:下拉刷新,上拉加载

//
//  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.
    }
    */

}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值