Pull to Refresh 拖动刷新之我的实现

简介:
项目中需要用到pull to refresh这个功能, 从网上找了下找到了这个: https://github.com/leah/PullToRefresh
这个代码对我来说有一个很大的问题。其中拖动刷新的实现是放在TableViewControllerL里的,我要的放在
自定义UIView中的实现。经过一番改造终于实现了出来。

首先,我们整个的拖动刷新都是从拖动操作发起的,如下的方法必须予以合适的实现:

?
1
2
3
4
5
6
7
8
9
10
// 拖动动作开始,如果正在获取更多信息不做任何操作
- ( void )scrollViewWillBeginDragging:(UIScrollView *)scrollView;
 
 
// 拖动中。根据是否已经开始加载信息设置tableView的contentInset值
- ( void )scrollViewDidScroll:(UIScrollView *)scrollView;
 
 
// 拖动完成,开始加载。如果上次的加载没有完成,不做任何操作
- ( void )scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:( BOOL )decelerate;


拖动相关的了解之后。拖动之前需要在初始化方法里做好准备工作。
设置下什么“拖动获取更多”,“加载中。。。”之类的文字。还有箭头,ActivityIndicator之类的界面元素。

然后就是根据加载的不同状态设置界面语速的文字,位置和隐藏与否。代码:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#pragma mark -
#pragma mark Pull to refresh methods
 
- ( void )setUpStrings{
 
_textPull = [[ NSString alloc]initWithString:@ "拖动获取更多。。。" ];
_textRelease = [[ NSString alloc]initWithString:@ "释放获取更多。。。" ];
_textRelease = [[ NSString alloc]initWithString:@ "加载中。。。" ];
}
 
- ( void )addPullToRefreshHeader{
 
CGRect mainBounds = [[UIScreen mainScreen] bounds];
_refreshHeaderView = [[UIView alloc]initWithFrame:CGRectMake(0, 0 - REFRESH_HEADER_VIEW, mainBounds.size.width, REFRESH_HEADER_VIEW)];
_refreshHeaderView.backgroundColor = [UIColor clearColor];
 
_refreshLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, mainBounds.size.width, REFRESH_HEADER_VIEW)];
_refreshLabel.backgroundColor = [UIColor clearColor];
_refreshLabel.font = [UIFont boldSystemFontOfSize:12.f];
_refreshLabel.textAlignment = UITextAlignmentCenter;
 
_refreshArrow = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@ "arrow.png" ]];
_refreshArrow.frame = CGRectMake(floorf((REFRESH_HEADER_VIEW - 20) / 2), floorf((REFRESH_HEADER_VIEW - 20) / 2), 27, 44);
 
_refreshSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
_refreshSpinner.frame = CGRectMake(floorf((REFRESH_HEADER_VIEW - 20) / 2), floorf((REFRESH_HEADER_VIEW - 20) / 2), 27, 44);
_refreshSpinner.hidesWhenStopped = YES ;
 
[_refreshHeaderView addSubview:_refreshLabel];
[_refreshHeaderView addSubview:_refreshArrow];
[_refreshHeaderView addSubview:_refreshSpinner];
[ self .weiboTableView addSubview:_refreshHeaderView];
}
 
- ( void )startLoading{
 
_isLoading = YES ;
 
[UIView animateWithDuration:0.3f animations:^{
 
self .weiboTableView.contentInset = UIEdgeInsetsMake(REFRESH_HEADER_VIEW, 0, 0, 0);
_refreshLabel.text = self .textLoading;
_refreshArrow.hidden = YES ;
[_refreshSpinner startAnimating];
}];
 
[ self refresh];
}
 
- ( void )stopLoadingComplete {
// Reset the header
_refreshLabel.text = self .textPull;
_refreshArrow.hidden = NO ;
[_refreshSpinner stopAnimating];
}
 
- ( void )stopLoading{
 
_isLoading = NO ;
 
[UIView animateWithDuration:0.3f animations:^{
 
self .weiboTableView.contentInset = UIEdgeInsetsZero;
[_refreshArrow layer].transform = CATransform3DMakeRotation(M_PI * 2, 0, 0, 1);
}
completion:^( BOOL finished){
[ self performSelector: @selector (stopLoadingComplete)];
}];
}
 
- ( void )refresh{
 
[ self performSelector: @selector (stopLoading) withObject: nil afterDelay:5.f];
}


最后最重要就是加载了。在加载方法中填充必要的代码,或者在子类的加载方法中添加(如果你要继承的话,最好还是继承一下)。示例:
?
1
2
3
4
5
6
- ( void )refresh{
 
// 加载功能代码
// 最后一句必不可少
[ self performSelector: @selector (stopLoading) withObject: nil afterDelay:5.f];
}


完整代码如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//
// ScrollRefreshPageView.h
// Sample Project
//
// Created by Bruce Li (mr_bruce).
// QQ: 1828099940
//
 
#import <UIKit/UIKit.h>
#import "TSPageView.h"
 
@interface ScrollRefreshPageView : UIView {
 
UIView *_refreshHeaderView;
UILabel *_refreshLabel;
UIImageView *_refreshArrow;
UIActivityIndicatorView *_refreshSpinner;
 
BOOL _isDragging;
BOOL _isLoading;
NSString *_textPull;
NSString *_textRelease;
NSString *_textLoading;
}
 
@property ( nonatomic , copy ) NSString *textPull;
@property ( nonatomic , copy ) NSString *textRelease;
@property ( nonatomic , copy ) NSString *textLoading;
 
- ( void )setUpStrings;
- ( void )addPullToRefreshHeader;
- ( void )startLoading;
- ( void )stopLoading;
- ( void )refresh;
 
@end


.m
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#import "ScrollRefreshPageView.h"
#import <QuartzCore/QuartzCore.h>
 
#define REFRESH_HEADER_VIEW 90.f
 
 
@implementation ScrollRefreshPageView
 
@synthesize textPull = _textPull;
@synthesize textRelease = _textRelease;
@synthesize textLoading = _textLoading;
 
- ( id )initWithFrame:(CGRect)frame
{
self = [ super initWithFrame:frame];
if ( self ) {
[ self setUpStrings];
[ self addPullToRefreshHeader];
}
return self ;
}
 
- ( void )dealloc{
 
[_refreshHeaderView release];
[_refreshLabel release];
[_refreshArrow release];
[_refreshSpinner release];
[_textPull release];
[_textRelease release];
[_textLoading release];
[ super dealloc];
}
 
#pragma mark -
#pragma mark Scroll view delegate
 
- ( void )scrollViewWillBeginDragging:(UIScrollView *)scrollView{
 
if (_isLoading) {
return ;
}
 
_isDragging = YES ;
}
 
- ( void )scrollViewDidScroll:(UIScrollView *)scrollView{
 
if (_isLoading) {
if (scrollView.contentOffset.y > 0) {
self .weiboTableView.contentInset = UIEdgeInsetsZero;
} else if (scrollView.contentOffset.y >= -REFRESH_HEADER_VIEW) {
self .weiboTableView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
}
} else if (_isDragging && scrollView.contentOffset.y < 0) {
[UIView animateWithDuration:0.25f animations:^{
 
if (scrollView.contentOffset.y < -REFRESH_HEADER_VIEW) {
_refreshLabel.text = self .textRelease;
[_refreshArrow layer].transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
}
else {
_refreshLabel.text = self .textPull;
[_refreshArrow layer].transform = CATransform3DMakeRotation(M_PI * 2, 0, 0, 1);
}
}];
}
}
 
- ( void )scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:( BOOL )decelerate{
 
if (_isLoading) {
return ;
}
 
_isDragging = NO ;
 
if (scrollView.contentOffset.y <= -REFRESH_HEADER_VIEW) {
[ self startLoading];
}
}
 
#pragma mark -
#pragma mark Pull to refresh methods
 
- ( void )setUpStrings{
 
_textPull = [[ NSString alloc]initWithString:@ "拖动获取更多。。。" ];
_textRelease = [[ NSString alloc]initWithString:@ "释放获取更多。。。" ];
_textRelease = [[ NSString alloc]initWithString:@ "加载中。。。" ];
}
 
- ( void )addPullToRefreshHeader{
 
CGRect mainBounds = [[UIScreen mainScreen] bounds];
_refreshHeaderView = [[UIView alloc]initWithFrame:CGRectMake(0, 0 - REFRESH_HEADER_VIEW, mainBounds.size.width, REFRESH_HEADER_VIEW)];
_refreshHeaderView.backgroundColor = [UIColor clearColor];
 
_refreshLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, mainBounds.size.width, REFRESH_HEADER_VIEW)];
_refreshLabel.backgroundColor = [UIColor clearColor];
_refreshLabel.font = [UIFont boldSystemFontOfSize:12.f];
_refreshLabel.textAlignment = UITextAlignmentCenter;
 
_refreshArrow = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@ "arrow.png" ]];
_refreshArrow.frame = CGRectMake(floorf((REFRESH_HEADER_VIEW - 20) / 2), floorf((REFRESH_HEADER_VIEW - 20) / 2), 27, 44);
 
_refreshSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
_refreshSpinner.frame = CGRectMake(floorf((REFRESH_HEADER_VIEW - 20) / 2), floorf((REFRESH_HEADER_VIEW - 20) / 2), 27, 44);
_refreshSpinner.hidesWhenStopped = YES ;
 
[_refreshHeaderView addSubview:_refreshLabel];
[_refreshHeaderView addSubview:_refreshArrow];
[_refreshHeaderView addSubview:_refreshSpinner];
[ self .weiboTableView addSubview:_refreshHeaderView];
}
 
- ( void )startLoading{
 
_isLoading = YES ;
 
[UIView animateWithDuration:0.3f animations:^{
 
self .weiboTableView.contentInset = UIEdgeInsetsMake(REFRESH_HEADER_VIEW, 0, 0, 0);
_refreshLabel.text = self .textLoading;
_refreshArrow.hidden = YES ;
[_refreshSpinner startAnimating];
}];
 
[ self refresh];
}
 
- ( void )stopLoadingComplete {
// Reset the header
_refreshLabel.text = self .textPull;
_refreshArrow.hidden = NO ;
[_refreshSpinner stopAnimating];
}
 
- ( void )stopLoading{
 
_isLoading = NO ;
 
[UIView animateWithDuration:0.3f animations:^{
 
self .weiboTableView.contentInset = UIEdgeInsetsZero;
[_refreshArrow layer].transform = CATransform3DMakeRotation(M_PI * 2, 0, 0, 1);
}
completion:^( BOOL finished){
[ self performSelector: @selector (stopLoadingComplete)];
}];
}
 
- ( void )refresh{
 
[ self performSelector: @selector (stopLoading) withObject: nil afterDelay:5.f];
}
 
@end

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处!

















本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/archive/2012/07/15/2592663.html ,如需转载请自行联系原作者
相关文章
|
Windows
Adobe2023全套全网最新稳定版安装包下载
下文软件均为windows系统软件,其中2018版适合windows7/8/10/11系统,2021、2020、2023版适合windows10/11系统。MAC均有!Adobe大法更新到2023版 无论是专业人士还是业余爱好 都毫不犹豫相继尝鲜看看自己竟然还停留在17版 着实感觉到羞愧!
1086 0
|
2月前
|
人工智能 自然语言处理 前端开发
API赋能:从大模型到智能应用的“最短路径”
在AI技术迅猛发展的今天,大模型已成为智能应用的核心驱动力。本文探讨如何通过API这一“数据桥梁”,高效对接大模型,实现智能应用开发。内容涵盖API的核心价值、分类与适用场景,API对接的关键实践步骤,以及如何通过前后端分离、AI Agent和低代码平台等新范式提升开发效率。结合医疗影像分析与智能教育平台等案例,展示API如何改变传统开发模式。展望未来,随着模型即服务(MaaS)和智能化API的发展,智能应用开发将迈向更广阔的新时代。
|
缓存 前端开发 Java
SpringBoot&SpringMVC统一异常处理之RestControllerAdvice
SpringBoot&SpringMVC统一异常处理之RestControllerAdvice
257 0
|
虚拟化 Windows
Windows Server 2016 中文版、英文版下载 (2025 年 6 月更新)
Windows Server 2016 中文版、英文版下载 (2025 年 6 月更新)
533 0
|
9月前
|
机器学习/深度学习 人工智能 算法
【AI系统】AI 编译器后端优化
AI编译器采用多层架构,首先通过前端优化将不同框架的模型转化为统一的Graph IR并进行计算图级别的优化,如图算融合、内存优化等。接着,通过后端优化,将优化后的计算图转换为TensorIR,针对单个算子进行具体实现优化,包括循环优化、算子融合等,以适应不同的硬件架构,最终生成高效执行的机器代码。后端优化是提升算子性能的关键步骤,涉及复杂的优化策略和技术。
287 3
|
10月前
|
域名解析 存储 缓存
DNS是什么?内网电脑需要配置吗?
【10月更文挑战第22天】DNS是什么?内网电脑需要配置吗?
1831 1
|
机器学习/深度学习 人工智能 TensorFlow
如何将OpenCV与AI深度学习结合使用
如何将OpenCV与AI深度学习结合使用
528 1
|
设计模式 C++ 开发者
C++一分钟之-智能指针:unique_ptr与shared_ptr
【6月更文挑战第24天】C++智能指针`unique_ptr`和`shared_ptr`管理内存,防止泄漏。`unique_ptr`独占资源,离开作用域自动释放;`shared_ptr`通过引用计数共享所有权,最后一个副本销毁时释放资源。常见问题包括`unique_ptr`复制、`shared_ptr`循环引用和裸指针转换。避免这些问题需使用移动语义、`weak_ptr`和明智转换裸指针。示例展示了如何使用它们管理资源。正确使用能提升代码安全性和效率。
262 2
|
安全 JavaScript 前端开发
JavaScript 中的模板字面量与标签模板
在 JavaScript 中,模板字面量(Template Literals)和标签模板(Tagged Templates)是两种用于处理字符串的特殊方式。它们分别提供了更灵活和强大的字符串处理能力,让字符串拼接、格式化和转义变得更加方便。
392 0
|
机器学习/深度学习 数据可视化 Python
python逻辑回归预测之信用卡逾期实战(附源码)
python逻辑回归预测之信用卡逾期实战(附源码)
873 0
python逻辑回归预测之信用卡逾期实战(附源码)