原来UIScrollView自带了一个下拉刷新的控件。但是并不是那么好用,于是做了一些封装。
UIRefreshControl:
发现UIRefreshControl 很简洁,
- refreshing 一个状态属性
- tintColor 一个菊花圈圈的颜色
- attributedTitle 一个刷新时显示的文字
- -(void) beginRefreshing 开始刷新, 根据偏移量 会自动进入刷新。
- -(void) endRefreshing 结束刷新,必须自己调用
不难发现这边少了一个开始刷新的回调。简单一点的我们可以这么做:
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
if (self.refresh.isRefreshing) {
NSLog(@"开始刷新了😝");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.refresh endRefreshing];
});
}
NSLog(@"y = %f , x = %f", scrollView.contentOffset.y, scrollView.contentOffset.x);
}
但是每次都去写一个代理,看起来并不是那么友好啊。所以有了下面的事情:
#import "UIScrollView+LJRefresh.h"
#import <objc/runtime.h>
@interface UIScrollView ()
@property(nonatomic, strong)void(^refreshHandler)();
@end
@implementation UIScrollView (LJRefresh)
+(void)load{
Method originalMethod = class_getInstanceMethod([self class], NSSelectorFromString(@"handlePan:"));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(customPanGesture:));
method_exchangeImplementations(originalMethod, swizzledMethod);
}
static char refreshBlockKey;
-(void (^)())refreshHandler{
return objc_getAssociatedObject(self, &refreshBlockKey);
}
-(void)setRefreshHandler:(void (^)())refreshHandler{
objc_setAssociatedObject(self, &refreshBlockKey, refreshHandler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(void)addSystemHeadRefresh:(NSString *)title handler:(void (^)())handler{
UIRefreshControl* refresh = [[UIRefreshControl alloc]init];
NSAttributedString* attributeStr = [[NSAttributedString alloc]initWithString:title];
refresh.attributedTitle = attributeStr;
refresh.tintColor = [UIColor redColor];
self.refreshControl = refresh;
self.refreshHandler = handler;
}
-(void)customPanGesture:(UIPanGestureRecognizer *)gestureRecognizer{
if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
if (self.refreshControl.isRefreshing && self.refreshHandler) {
self.refreshHandler();
}
}
[self customPanGesture:gestureRecognizer];
}
-(void)beginSystemHeadRefresh{
[self.refreshControl beginRefreshing];
}
-(void)endSystemHeadRefresh{
[self.refreshControl endRefreshing];
}
@end
没错,就是写个UIScrollView的分类,再把ScrollView上面原来的Pan手势的Action 用黑魔法转换,再监听手势结束后的状态。就是我们需要的开始刷新状态了。
使用的时候 就这么着:
@weakify(self);
[self.contentScrollView addSystemHeadRefresh:@"😁😎😆hello" handler:^{
@strongify(self);
DLog(@" 开始刷新啦`````");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.35*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.contentScrollView endSystemHeadRefresh];
});
}];