利用类别实现tableView自带上拉加载以及下拉刷新效果 当然该功能需要MJRefresh第三方库支持 添加 MJRefresh 并导入头文件
然后进行下一步接下来直接上代码:
首先 .h 文件
//该功能需 MJRefresh 第三方库支持
#import <UIKit/UIKit.h>
@protocol UITableViewRefreshDelegate;
@protocol UITableViewUploadDelegate;
@interface UITableView (RefreshData)
/**为方便操作与StoryBoard连线,将下拉刷新与上拉加载代理分开*/
@property (nonatomic, weak) IBOutlet id<UITableViewRefreshDelegate> refreshDelegate;//下拉刷新的代理
@property (nonatomic, weak) IBOutlet id<UITableViewUploadDelegate> uploadDelegate;// 上拉加载的代理
// 下拉刷新方法
- (void)beginRefresh;
// 上拉加载方法
- (void)beginUpload;
@end
@protocolUITableViewRefreshDelegate
@optional
- (void)dataRequestWithRefresh:(BOOL)isRefresh complete:(void(^)(BOOLisFulfill))complete;
@end
@protocolUITableViewUploadDelegate
@optional
- (void)dataRequestWithRefresh:(BOOL)isRefresh complete:(void(^)(BOOLisFulfill))complete;
@end
.m文件
#import "UITableView+RefreshData.h"
#import <objc/runtime.h>
@interface REWeakObjectContainer :NSObject
@property (nonatomic, readonly, weak) id weakObject;
- (instancetype)initWithWeakObject:(id)object;
@end
#pragma mark - UITableView+RefreshData
static char const * const kRefreshDelegate = "refreshDelegate";
static char const * const kUploadDelegate = "uploadDelegate";
@implementation UITableView (RefreshData)
#pragma mark - Getters (Public)
- (id<UITableViewRefreshDelegate>)refreshDelegate
{
REWeakObjectContainer *container = objc_getAssociatedObject(self, kRefreshDelegate);
return container.weakObject;
}
- (id<UITableViewUploadDelegate>)uploadDelegate
{
REWeakObjectContainer *container = objc_getAssociatedObject(self, kUploadDelegate);
return container.weakObject;
}
- (void)beginRefresh {
[self re_beginRefresh];
}
- (void)beginUpload {
[self re_beginUpload];
}
#pragma mark - Delegate Getters & Events (Private)
- (void)re_beginRefresh {
if(self.refreshDelegate&& [self.refreshDelegate respondsToSelector:@selector(dataRequestWithRefresh:complete:)]) {
if(self.mj_header) {
[self.mj_header beginRefreshing];
}
}
}
- (void)re_beginUpload {
if(self.uploadDelegate&& [self.uploadDelegate respondsToSelector:@selector(dataRequestWithRefresh:complete:)]) {
if(self.mj_footer) {
[self.mj_footer beginRefreshing];
}
}
}
- (void)headerRefereshing {
__weak typeof(self) weakself = self;
// 1.请求数据
[self.refreshDelegate dataRequestWithRefresh:YES complete:^(BOOL isFulfill) {
// 结束下拉刷新状态
[weakself.mj_header endRefreshing];
[weakself reloadData];
}];
}
- (void)footerRefereshing {
__weaktypeof (self) weakself = self;
// 1.请求数据
[self.uploadDelegate dataRequestWithRefresh:NO complete:^(BOOL isFulfill) {
//结束上拉加载状况
if(isFulfill) {
[weakself.mj_footer endRefreshing];
} else {
[weakself.mj_footer endRefreshingWithNoMoreData];
}
// 刷新表格
[weakself reloadData];
}];
}
#pragma mark - Setters (Public)
- (void)setRefreshDelegate:(id<UITableViewRefreshDelegate>)refreshDelegate
{
objc_setAssociatedObject(self, kRefreshDelegate, [[REWeakObjectContainer alloc] initWithWeakObject:refreshDelegate], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
__weak __typeof(self) weakSelf = self;
MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[weakSelf headerRefereshing];
}];
self.mj_header = header;
}
- (void)setUploadDelegate:(id<UITableViewUploadDelegate>)uploadDelegate
{
objc_setAssociatedObject(self, kUploadDelegate, [[REWeakObjectContainer alloc] initWithWeakObject:uploadDelegate], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
__weak __typeof(self) weakSelf = self;
MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
[weakSelf footerRefereshing];
}];
self.mj_footer = footer;
}
@end
#pragma mark - REWeakObjectContainer
@implementation REWeakObjectContainer
- (instancetype)initWithWeakObject:(id)object
{
self= [super init];
if(self) {
_weakObject = object;
}
return self;
}
@end
这样 代码就上完了,然后编译,导入头文件。 我们来看看效果:
效果图我们能很清楚地看到 这时候StoryBoard上 tableView已经具有refreshDelegate和uploadDelegate两项可以连接了,OK 连上,在ViewController里遵守该协议
这是代码图OK 代码就是这样。下面来看看效果:
下拉刷新 上拉加载这样就完成了相应的效果,接下来在使用的时候只要设置相应代理,就可以简单实现刷新效果。至于为什么两个代理要分开设 上面已经解释过,有的tableView并不需要上拉加载,如果不分开虽然也能处理,但需要添加额外方法,不如分开来使。
网友评论