关于MJRefresh 上拉刷新无法停止的解决方法


事件详情:tableView上拉后不断刷新,基本上无法停止.

出现该事件的场景:在tableView中添加了多个自定义的Cell,当cell的总高度超出屏幕时即出现事件.下拉刷新无法回收并持续刷新.

 

解决方案:

以下是我对MJRefresh的功能封装.注意下面代码中红色部分.MJRefresh中定义了多个Header和Footer刷新类型.用错类型会导致不确定的问题发生.

之前导至我持续刷新的类是  MJRefreshAutoNormalFooter 我将其更换成 MJRefreshBackNormalFooter 后就没有更出现类似问题了.

 

另外如果在停止刷新时表格会出现跳一下(抖一下)等情况时.使用

self.tableView.mj_header.endRefreshing { weakSelf.tableView.reloadData() } 在加载动画结束block或swift闭包回调中再做数据刷新就不会有这个问题了.

其它碰到的问题

刷新完后表格仍然向上跳一节.但不会抖

1.可能是 tableView!.estimatedRowHeight 值设置过小.我试着加大了该值.表格就不跳了.

2.约束错有误.详细查看右下角的输出信息.如果有出现约束问题.解决就好了.

 

追加:因转战swift贴出swift中的个人封装.仅供参考.

 

**********************************分隔****************************************

 

import Foundation

import UIKit

import MJRefresh

extension UITableView { // 对tableView写一个扩展 

    

    //MARK:---- header ----

    

    /// 全局配置

    ///

    /// - Parameter header: mj_header

    private class func xh_MJRefreshHeader(header:MJRefreshNormalHeader) {

        header.isAutomaticallyChangeAlpha = true

    }

    

    /// mjheader刷新

    ///

    /// - Parameter completionHandle: 回调(配置刷新需要做的事)当header刷新时调用

    /// - Returns: 返回MJRefreshNormalHeader,如需要特殊配置时可接收使用.

    @discardableResult func xh_MJRefreshHeader(completionHandle:@escaping MJRefreshComponentRefreshingBlock) -> MJRefreshNormalHeader {

        let header = MJRefreshNormalHeader.init(refreshingBlock: completionHandle)

        self.mj_header = header

        UITableView.xh_MJRefreshHeader(header: header!)

        return header!

    }

    

    /// mjheader刷新

    ///

    /// - Parameters:

    ///   - IdleTitle: 空闲状态标题

    ///   - WillRefreshTitle: 即将刷新(拖动时)标题

    ///   - RefreshingTitle: 刷新中标题

    ///   - completionHandle: 回调(配置刷新需要做的事)当header刷新时调用

    /// - Returns: 返回MJRefreshNormalHeader,如需要特殊配置时可接收使用.

    @discardableResult func xh_MJRefreshHeader(IdleTitle:String,WillRefreshTitle:String,RefreshingTitle:String,completionHandle:@escaping MJRefreshComponentRefreshingBlock) -> MJRefreshNormalHeader {

        let header = MJRefreshNormalHeader.init(refreshingBlock: completionHandle)

        self.mj_header = header

        UITableView.xh_MJRefreshHeader(header: header!)

        header?.setTitle(IdleTitle, for: .idle)

        header?.setTitle(WillRefreshTitle, for: .willRefresh)

        header?.setTitle(RefreshingTitle, for: .refreshing)

        return header!

    }

    

    //MARK:---- footer ----

    

    /// footer全局配置

    ///

    /// - Parameter footer: mj_footer

    private class func xh_MJRefreshFooterSetup(footer:MJRefreshBackNormalFooter) {

        footer.isAutomaticallyChangeAlpha = true // 设置自动切换透明度(在导航栏下面自动隐藏)

    }

    

    /// mjfooter刷新

    ///

    /// - Parameter completionHandle: 回调(配置刷新需要做的事)当footer刷新时调用

    /// - Returns: 返回MJRefreshBackNormalFooter,如需要特殊配置时可接收使用.

    @discardableResult func xh_MJRefreshFooter(completionHandle:@escaping MJRefreshComponentRefreshingBlock) -> MJRefreshBackNormalFooter {

        let footer = MJRefreshBackNormalFooter.init(refreshingBlock: completionHandle)

        self.mj_footer = footer

        UITableView.xh_MJRefreshFooterSetup(footer: footer!)

        return footer!

    }

    

    /// mjfooter刷新

    ///

    /// - Parameters:

    ///   - IdleTitle: 空闲状态标题

    ///   - WillRefreshTitle: 即将刷新(拖动时)标题

    ///   - RefreshingTitle: 刷新中标题

    ///   - completionHandle: 回调(配置刷新需要做的事)当footer刷新时调用

    /// - Returns: 返回MJRefreshBackNormalFooter,如需要特殊配置时可接收使用.

    @discardableResult func xh_MJRefreshFooter(IdleTitle:String,WillRefreshTitle:String,RefreshingTitle:String,completionHandle:@escaping MJRefreshComponentRefreshingBlock) -> MJRefreshBackNormalFooter {

        // 使用 MJRefreshAutoNormalFooter 中的 triggerAutomaticallyRefreshPercent 可以控制刷新高度

        let footer = MJRefreshBackNormalFooter.init(refreshingBlock: completionHandle)

        self.mj_footer = footer

        UITableView.xh_MJRefreshFooterSetup(footer: footer!)

        footer?.setTitle(IdleTitle, for: .idle)

        footer?.setTitle(WillRefreshTitle, for: .willRefresh)

        footer?.setTitle(RefreshingTitle, for: .refreshing)

        return footer!

    }

    

    

    //MARK:---- other ----

    

    /// 停止MJ刷新(header 和 footer都停止) 会自动刷新表格数据.一定要放在数据处理完后调用,否则不出现数据 要自动刷新表格数据的调这个.

    func xh_endMJRefresh() {

        if self.mj_header?.isRefreshing == true {

            self.mj_header.endRefreshing { self.reloadData() }

        } else if self.mj_footer?.isRefreshing == true {

            self.mj_footer.endRefreshing { self.reloadData() }

        } else { self.reloadData() }// 第一次进入页面拉取数据时.可能header和footer都没有.所以在这里刷新一下数据

    }

    

    /// 停止MJ刷新(header 和 footer都停止) 需要在回调中处理数据的调这个

    ///

    /// - Parameter completion: 完成回调

    func xh_endMJRefresh(completion:@escaping () -> Void) {

        if self.mj_header?.isRefreshing == true {

            self.mj_header.endRefreshing { completion() }

        } else if self.mj_footer?.isRefreshing == true {

            self.mj_footer.endRefreshing { completion() }

        } else { completion() }

    }

 

 

    /// 开始MJHeader刷新

    func xh_beginMJHeaderRefresh() {

        self.mj_header.beginRefreshing()

    }

    

    /// 开始MJFooter刷新

    func xh_BeginMJFooterRefresh() {

        self.mj_footer.beginRefreshing()

    }

    

    /// 停止MJFooter刷新,并设置为没有更多数据

    func xh_endMJFooterRefreshWithNoMoreData() {

        self.mj_footer.endRefreshingWithNoMoreData()

    }

    

}

 

**********************************分隔****************************************

 

使用例子:

    

      tableView?.xh_MJRefreshHeader {// 配置mjHeader .footer配置略

            weakSelf?.dosomething()

        }

 

结束刷新:

    //在刷新前要做好数据处理.刷新功能中已经写了让表格数据刷新

    self.infoList += list// 先把数据处理好.

    tableView?.xh_endMJRefresh()// 最后停止动画.会在动画结束后自动刷新数据.

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM