前言
講下拉刷新及上拉加載之前先給大家解釋UIScrollView的幾個屬性
- contentSize是UIScrollView可以滾動的區域。
- contentOfinset 蘋果官方文檔的解釋是"內容視圖嵌入到封閉的滾動視圖的距離,我的理解是他實際上就是scrollView的Content View相對於scrollView的外殼的邊距,他其實和CSS中的pading屬性有點相似。
- contentOffset是UIScrollView當前顯示區域的頂點相對於frame頂點的偏移量,例如上面的例子如果拉到最下面,則contentOffset就是(0, 480),也就是y偏移了480.
下拉刷新及上拉加載原理
- 下拉刷新實際上是監測UIScrollView的contentOffset的y值,當他往下拉動時,UIScrollView的contentOffset是一直減小的,然後把通過動畫把它的contentInset值控制成一個定值,然後通過設置延時來把UIScrollView的contentInset的值恢復原點。啥話不說,上代碼
//下拉刷新
if (scrollView.contentOffset.y < -100) {
[UIView animateWithDuration:1.0 animations:^{
self.scrollView.contentInset = UIEdgeInsetsMake(100, 0, 0, 0);
} completion:^(BOOL finished) {
NSLog(@"發起下拉刷新");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:1.0 animations:^{
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
}];
});
}];
}
- 上拉加載其實原理和下拉刷新基本是一樣的,只不過判斷的contentOffset的值不同,如果scrollView.bounds.size.height + scrollView.contentOffset.y >scrollView.contentSize.height,說明你執行了上拉操作,然後實現起來基本就和下拉刷新是一樣的。
//上拉加載
if (scrollView.bounds.size.height + scrollView.contentOffset.y >scrollView.contentSize.height) {
[UIView animateWithDuration:1.0 animations:^{
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
} completion:^(BOOL finished) {
NSLog(@"發起上拉加載");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:1.0 animations:^{
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
}];
});
}];
}
下面奉上完整的demo代碼,大家看不懂的可以私聊我,要是想深入了解的話可以去github搜索MJRefresh看完整的別人封裝好的第三方
#import "ViewController.h"
@interface ViewController ()<UIScrollViewDelegate>
@property (nonatomic, strong) UIScrollView * scrollView;
@end
@implementation ViewController
- (UIScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
//contentSize是可滑動的區域
_scrollView.contentSize = CGSizeMake(0, 900);
_scrollView.backgroundColor = [UIColor grayColor];
_scrollView.delegate = self;
//greenView實際上就是UIScrollView的content View
UIView * greenView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 900)];
greenView.backgroundColor = [UIColor greenColor];
[_scrollView addSubview:greenView];
}
return _scrollView;
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
//下拉刷新-當下拉刷新時,contentOffset實際上就是greenView相對於屏幕左上角的偏移量。
if (scrollView.contentOffset.y < -100) {
[UIView animateWithDuration:1.0 animations:^{
self.scrollView.contentInset = UIEdgeInsetsMake(100, 0, 0, 0);
} completion:^(BOOL finished) {
NSLog(@"發起下拉刷新");
//設置延時時間為2秒
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:1.0 animations:^{
//恢復之前的contentInset,讓greenView回到原來的地方
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
}];
});
}];
}
//上拉加載
if (scrollView.bounds.size.height + scrollView.contentOffset.y >scrollView.contentSize.height) {
[UIView animateWithDuration:1.0 animations:^{
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
} completion:^(BOOL finished) {
NSLog(@"發起上拉加載");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:1.0 animations:^{
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
}];
});
}];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.view addSubview:self.scrollView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end