事件详情: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()// 最后停止动画.会在动画结束后自动刷新数据.