刷新是我们经常用到的功能,国内MJ的刷新三方库也是大多是app所采用的。不过新手在实现这一功能的时候都是直接拿过来使用而没有思考怎么实现这一功能,正好手上的项目差多了,自己抽个时候写一下刷新实现的过程,自己也顺便复习一下。嘿嘿嘿。
内置刷新
其实苹果对于tabeView,有内置的刷新控件。因为是官方的api 实现起来特别的简单,效果也不错。
//下拉刷新
UIRefreshControl *refreshC = [[UIRefreshControl alloc] init];
refreshC.attributedTitle = [[NSAttributedString alloc] initWithString:@"正在刷新中"];
refreshC.tintColor = [UIColor blueColor];
[refreshC addTarget:self action:@selector(pullRefresh) forControlEvents:UIControlEventValueChanged];
_refreshC = refreshC;
self.refreshControl = refreshC;
这边有一点要注意的是因为UIRefreshControl继承了UIControl 而且在h文件的注释中有这样的注释。
When a user has pulled-to-refresh, the UIRefreshControl fires its UIControlEventValueChanged event.
通过这两个条件就可以触发刷新事件的处理过程了。
在刷新 获取数据的过程中,采用异步加载。
- (void) pullRefresh {
//异步加载数据
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//加载数据
//加载完成之后停止刷新
//这里延时模拟
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_refreshC endRefreshing];
});
});
}
苹果提供的这个刷新控制类UIRefreshControl
实现起来简单便捷,不过也有部分的局限。苹果只提供了对颜色和文字的接口,如果自己想实现帅气的动画那就需要自己自动已刷新控件了。
自定义刷新
有时候不得不自定义刷新效果,因为系统只提供了下拉刷新,而上拉刷新必须要我们自己去实现。
其实自定义刷新效果也不难了。模仿系统的刷新效果,完全可以自己做一个。
我就说下我的思路 贴下代码。纯入门级别的,没有难点。
1 首先声明下拉刷新需要的控件(我是由一个一个label 和一个 indicator组成)
设置一些ui(位置都是写死的,童鞋恩不要太在意细节)
@property (nonatomic, strong) UIView *bottomBackView;
@property (nonatomic, strong) UILabel *bottomLabel;
@property (nonatomic, strong) UIActivityIndicatorView *bottomIndicatorView;
- (void) setBottomRefreshUI {
//获取 tableview contentSize 的大小
CGFloat BackViewY = self.tableView.contentSize.height + CGRectGetMaxY(self.tableView.frame);
_bottomBackView = [[UIView alloc] initWithFrame:CGRectMake(0, BackViewY, CGRectGetWidth(self.tableView.frame), 80)];
_bottomIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(100, 20, 20, 20)];
_bottomIndicatorView.color = [UIColor blackColor];
[_bottomBackView addSubview:_bottomIndicatorView];
_bottomLabel = [[UILabel alloc] initWithFrame:CGRectMake(150, 20, 200, 30)];
_bottomLabel.text = @"上拉刷新";
[self.bottomBackView addSubview:_bottomLabel];
// [self.view addSubview:_bottomBackView];
[self.view insertSubview:_bottomBackView atIndex:0];
}
这边要注意的是 刷新视图要放在最下面
2 之后需要监听tableview 的contentOffset(我这边设置的是当偏移量超过80的时候就触发刷新效果)
这边要注意的是 偏移量不是直接就是contentOffset 这边要通过contentOffset和contentSize 以及屏幕的高度(这个是相对的)计算出来的。
//上拉刷新
[self setBottomRefreshUI];
[self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
#pragma mark kvo
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
if ([keyPath isEqualToString:@"contentOffset"]) {
UITableView *tableView = (UITableView *)object;
CGPoint contentOffset = [[change valueForKey:NSKeyValueChangeNewKey] CGPointValue];
if (((contentOffset.y + screenHeight -tableView.contentSize.height) > 80)&&tableView.contentSize.height > 0) {
NSLog(@"%f===%f",contentOffset.x,contentOffset.y);
self.bottomBackView.center = CGPointMake(tableView.center.x, tableView.contentSize.height+40);
[self beginRefresh];
}
}
}
3 当达到触发事件
改变刷新视图的ui 以及异步加载所需要的数据
- (void) beginRefresh {
self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 100, 0);
[_bottomIndicatorView startAnimating];
_bottomLabel.text = @"松开开始刷新";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.1 animations:^{
self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
}completion:^(BOOL finished) {
[_bottomIndicatorView stopAnimating];
_bottomLabel.text = @"上拉开始刷新";
}];
});
}
到这边就over了,上面是我自己写着玩的 ,代码也没有封装。大家不要介意。嘿嘿···
当然MJ的刷新我在这就不介绍了,太流行了,大家直接到看看他的readme 就可以了。。。