版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】iOS中怎么實(shí)現(xiàn)一個(gè)下拉、上拉刷新控件
iOS中怎么實(shí)現(xiàn)一個(gè)下拉、上拉刷新控件,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題??刂破鱒iewController:#import
<UIKit/UIKit.h>
@interface
ViewController
:
UIViewController
@end
/***
分割線
***/
#import
"ViewController.h"
#import
"HWRefresh.h"
@interface
ViewController
()<UITableViewDataSource,
UITableViewDelegate>
@property
(nonatomic,
strong)
NSMutableArray
*array;
@property
(nonatomic,
strong)
UITableView
*tableView;
@property
(nonatomic,
assign)
NSInteger
page;
@end
@implementation
ViewController
-
(NSMutableArray
*)array
{
if
(!_array)
{
_array
=
[NSMutableArray
array];
}
return
_array;
}
-
(void)viewDidLoad
{
[super
viewDidLoad];
self.view.backgroundColor
=
[UIColor
blackColor];
self.page
=
1;
//模擬獲取信息
[self
getInfo];
//創(chuàng)建控件
[self
creatControl];
//添加頭部刷新
[self
addHeaderRefresh];
//添加尾部刷新
[self
addFooterRefresh];
}
-
(void)getInfo
{
NSArray
*array
=
@[@"iOS
HERO博客",
@"iOS
HERO博客",
@"iOS
HERO博客",
@"iOS
HERO博客",
@"/hero_wqb"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(2.0f
*
NSEC_PER_SEC)),
dispatch_get_main_queue(),
^{
if
(self.page
==
1)
{
self.array
=
[NSMutableArray
arrayWithArray:array];
}else{
[self.array
addObjectsFromArray:array];
}
[_tableView
reloadData];
[_tableView
headerEndRefreshing];
[_tableView
footerEndRefreshing];
NSLog(@"已經(jīng)刷新好了");
});
}
-
(void)creatControl
{
//列表視圖
_tableView
=
[[UITableView
alloc]
initWithFrame:CGRectMake(20,
64,
[[UIScreen
mainScreen]
bounds].size.width
-
100,
[[UIScreen
mainScreen]
bounds].size.height
-
164)
style:UITableViewStylePlain];
_tableView.dataSource
=
self;
_tableView.delegate
=
self;
[self.view
addSubview:_tableView];
}
-
(void)addHeaderRefresh
{
__weak
typeof(self)
weakSelf
=
self;
[_tableView
addHeaderRefreshWithCallback:^{
__strong
typeof(weakSelf)
strongSelf
=
weakSelf;
strongSelf.page
=
1;
[strongSelf
getInfo];
}];
}
-
(void)addFooterRefresh
{
__weak
typeof(self)
weakSelf
=
self;
[_tableView
addFooterRefreshWithCallback:^{
__strong
typeof(weakSelf)
strongSelf
=
weakSelf;
strongSelf.page
++;
[strongSelf
getInfo];
}];
}
#pragma
mark
-
UITableViewDataSource
-
(NSInteger)tableView:(UITableView
*)tableView
numberOfRowsInSection:(NSInteger)section
{
return
self.array.count;
}
-
(UITableViewCell
*)tableView:(UITableView
*)tableView
cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
static
NSString
*identifier
=
@"refreshTest";
UITableViewCell
*cell
=
[tableView
dequeueReusableCellWithIdentifier:identifier];
if
(!cell)
{
cell
=
[[UITableViewCell
alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier];
}
cell.textLabel.text
=
[_array[indexPath.row]
stringByAppendingString:[NSString
stringWithFormat:@"_%ld",
indexPath.row]];
return
cell;
}
-
(void)scrollViewDidScroll:(UIScrollView
*)scrollView
{
//滑動(dòng)到底部自動(dòng)刷新
if
(_tableView.contentSize.height
>
_tableView.frame.size.height
&&
_tableView.contentOffset.y
+
_tableView.frame.size.height
>
_tableView.contentSize.height
-
40
&&
_page
<
50)
{
[_tableView
footerBeginRefreshing];
}
}
@end刷新基類HWRefreshBaseView:#import
<UIKit/UIKit.h>
#define
HWRefreshContentOffset
@"contentOffset"
typedef
enum
{
HWRefreshStateNormal
=
0,
//普通狀態(tài)
HWRefreshStatePulling,
//釋放即可刷新的狀態(tài)
HWRefreshStateRefreshing,
//正在刷新中的狀態(tài)
}
HWRefreshState;
@interface
HWRefreshBaseView
:
UIView
@property
(nonatomic,
weak)
UIScrollView
*scrollView;
@property
(nonatomic,
copy)
NSString
*pullToRefreshText;
@property
(nonatomic,
copy)
NSString
*releaseToRefreshText;
@property
(nonatomic,
copy)
NSString
*refreshingText;
@property
(nonatomic,
copy)
void
(^refreshingCallback)();
@property
(nonatomic,
assign)
HWRefreshState
state;
@property
(nonatomic,
assign)
UIEdgeInsets
scrollViewOriginalInset;
-
(void)beginRefreshing;
-
(void)endRefreshing;
@end
/***
分割線
***/
#import
"HWRefreshBaseView.h"
#define
KHWRefreshViewHeight
44.0f
#define
KImageW
30.0f
#define
KLabelW
100.0f
@interface
HWRefreshBaseView
()
@property
(nonatomic,
weak)
UILabel
*rLabel;
@property
(nonatomic,
weak)
UIImageView
*rImageView;
@end
@implementation
HWRefreshBaseView
-
(instancetype)initWithFrame:(CGRect)frame
{
frame.size.height
=
KHWRefreshViewHeight;
if
(self
=
[super
initWithFrame:frame])
{
CGFloat
imageH
=
30.f;
CGFloat
labelH
=
20.f;
CGFloat
imageX
=
([UIScreen
mainScreen].bounds.size.width
-
KImageW
-
KLabelW)
*
0.5;
CGFloat
imageY
=
(KHWRefreshViewHeight
-
imageH)
*
0.5;
CGFloat
labelY
=
(KHWRefreshViewHeight
-
labelH)
*
0.5;
//圖片
UIImageView
*rImageView
=
[[UIImageView
alloc]
initWithFrame:CGRectMake(imageX,
imageY,
KImageW,
imageH)];
rImageView.image
=
[UIImage
imageNamed:@"refreshing.jpg"];
[self
addSubview:rImageView];
self.rImageView
=
rImageView;
//標(biāo)簽
UILabel
*rLabel
=
[[UILabel
alloc]
initWithFrame:CGRectMake(CGRectGetMaxX(rImageView.frame),
labelY,
KLabelW,
labelH)];
rLabel.text
=
self.pullToRefreshText;
rLabel.font
=
[UIFont
systemFontOfSize:14.0f];
rLabel.textAlignment
=
NSTextAlignmentCenter;
[self
addSubview:rLabel];
self.rLabel
=
rLabel;
}
return
self;
}
-
(void)willMoveToSuperview:(UIView
*)newSuperview
{
[super
willMoveToSuperview:newSuperview];
//舊的父控件
[self.superview
removeObserver:self
forKeyPath:HWRefreshContentOffset
context:nil];
//新的父控件
if
(newSuperview)
{
[newSuperview
addObserver:self
forKeyPath:HWRefreshContentOffset
options:NSKeyValueObservingOptionNew
context:nil];
//記錄UIScrollView
_scrollView
=
(UIScrollView
*)newSuperview;
//記錄UIScrollView最開始的contentInset
_scrollViewOriginalInset
=
_scrollView.contentInset;
}
//居中顯示圖片、提示信息
CGRect
temFrame
=
_rImageView.frame;
temFrame.origin.x
=
(newSuperview.frame.size.width
-
KImageW
-
KLabelW)
*
0.5;
_rImageView.frame
=
temFrame;
CGRect
tf
=
_rLabel.frame;
tf.origin.x
=
CGRectGetMaxX(_rImageView.frame);
_rLabel.frame
=
tf;
}
-
(void)setPullToRefreshText:(NSString
*)pullToRefreshText
{
_pullToRefreshText
=
pullToRefreshText;
self.rLabel.text
=
pullToRefreshText;
}
-
(void)setState:(HWRefreshState)state
{
if
(_state
==
state)
return;
switch
(state)
{
case
HWRefreshStateNormal:
{
[self
stopAnimating];
self.rLabel.text
=
self.pullToRefreshText;
break;
}
case
HWRefreshStatePulling:
{
self.rLabel.text
=
self.releaseToRefreshText;
break;
}
case
HWRefreshStateRefreshing:
{
[self
startAnimating];
self.rLabel.text
=
self.refreshingText;
if
(self.refreshingCallback)
self.refreshingCallback();
break;
}
default:
break;
}
_state
=
state;
}
//開始刷新
-
(void)beginRefreshing
{
self.state
=
HWRefreshStateRefreshing;
}
//結(jié)束刷新
-
(void)endRefreshing
{
self.state
=
HWRefreshStateNormal;
}
//開始動(dòng)畫
-
(void)startAnimating
{
NSMutableArray
*array
=
[NSMutableArray
array];
for
(int
i
=
0;
i
<
2;
i++)
{
NSString
*imageName
=
[NSString
stringWithFormat:@"refreshing%02d.jpg",
i
+
1];
UIImage
*image
=
[UIImage
imageNamed:imageName];
[array
addObject:image];
}
[_rImageView
setAnimationImages:array];
[_rImageView
setAnimationDuration:0.3f];
[_rImageView
startAnimating];
}
//結(jié)束動(dòng)畫
-
(void)stopAnimating
{
if
(_rImageView.isAnimating)
{
[_rImageView
stopAnimating];
[_rImageView
performSelector:@selector(setAnimationImages:)
withObject:nil
afterDelay:0];
}
}
@end頭部刷新HWRefreshHeader:#import
"HWRefreshBaseView.h"
@interface
HWRefreshHeader
:
HWRefreshBaseView
+
(instancetype)header;
@end
/***
分割線
***/
#import
"HWRefreshHeader.h"
@implementation
HWRefreshHeader
+
(instancetype)header
{
return
[[HWRefreshHeader
alloc]
init];
}
-
(instancetype)initWithFrame:(CGRect)frame
{
if
(self
=
[super
initWithFrame:frame])
{
self.pullToRefreshText
=
@"下拉即可刷新";
self.releaseToRefreshText
=
@"釋放即可刷新";
self.refreshingText
=
@"刷新中...";
}
return
self;
}
-
(void)willMoveToSuperview:(UIView
*)newSuperview
{
[super
willMoveToSuperview:newSuperview];
//設(shè)置自己的位置和尺寸
CGRect
frame
=
self.frame;
frame.origin.y
=
-
self.frame.size.height;
self.frame
=
frame;
}
-
(void)observeValueForKeyPath:(NSString
*)keyPath
ofObject:(id)object
change:(NSDictionary
*)change
context:(void
*)context
{
//不能跟用戶交互或正在刷新就直接返回
if
(!self.userInteractionEnabled
||
self.alpha
<=
0.01
||
self.hidden
||
self.state
==
HWRefreshStateRefreshing)
return;
//根據(jù)偏移量設(shè)置相應(yīng)狀態(tài)
if
([keyPath
isEqualToString:HWRefreshContentOffset])
{
[self
setStateWithContentOffset];
}
}
-
(void)setStateWithContentOffset
{
//當(dāng)前的contentOffset
CGFloat
currentOffsetY
=
self.scrollView.contentOffset.y;
//頭部控件剛好出現(xiàn)的offsetY
CGFloat
happenOffsetY
=
-
self.scrollViewOriginalInset.top;
//如果是向上滾動(dòng)到看不見頭部控件,直接返回
if
(currentOffsetY
>=
happenOffsetY)
return;
//滑動(dòng)時(shí)
if
(self.scrollView.isDragging)
{
//普通狀態(tài)和即將刷新狀態(tài)的臨界點(diǎn)
CGFloat
normalTopullingOffsetY
=
happenOffsetY
-
self.frame.size.height;
//轉(zhuǎn)為即將刷新狀態(tài)
if
(self.state
==
HWRefreshStateNormal
&&
currentOffsetY
<
normalTopullingOffsetY)
{
self.state
=
HWRefreshStatePulling;
//轉(zhuǎn)為普通狀態(tài)
}else
if
(self.state
==
HWRefreshStatePulling
&&
currentOffsetY
>=
normalTopullingOffsetY)
{
self.state
=
HWRefreshStateNormal;
}
//松手時(shí),如果是松開就可以進(jìn)行刷新的狀態(tài),則進(jìn)行刷新
}else
if
(self.state
==
HWRefreshStatePulling)
{
self.state
=
HWRefreshStateRefreshing;
}
}
-
(void)setState:(HWRefreshState)state
{
//若狀態(tài)未改變,直接返回
if
(self.state
==
state)
return;
//保存舊狀態(tài)
HWRefreshState
oldState
=
self.state;
//調(diào)用父類方法
[super
setState:state];
switch
(state)
{
case
HWRefreshStateNormal:
{
//如果由刷新狀態(tài)返回到普通狀態(tài)
if
(oldState
==
HWRefreshStateRefreshing)
{
[UIView
animateWithDuration:0.25f
animations:^{
UIEdgeInsets
inset
=
self.scrollView.contentInset;
inset.top
-=
self.frame.size.height;
self.scrollView.contentInset
=
inset;
}];
}
break;
}
case
HWRefreshStatePulling:
{
break;
}
case
HWRefreshStateRefreshing:
{
//執(zhí)行動(dòng)畫
[UIView
animateWithDuration:0.25f
animations:^{
CGFloat
top
=
self.scrollViewOriginalInset.top
+
self.frame.size.height;
//增加滾動(dòng)區(qū)域
UIEdgeInsets
inset
=
self.scrollView.contentInset;
inset.top
=
top;
self.scrollView.contentInset
=
inset;
//設(shè)置滾動(dòng)位置
CGPoint
offset
=
self.scrollView.contentOffset;
offset.y
=
-
top;
self.scrollView.contentOffset
=
offset;
}];
break;
}
default:
break;
}
self.state
=
state;
}
@end分類UIScrollView+HWRefresh:#import
<UIKit/UIKit.h>
@interface
UIScrollView
(HWRefresh)
//添加下拉刷新回調(diào)
-
(void)addHeaderRefreshWithCallback:(void
(^)())callback;
//讓下拉刷新控件停止刷新
-
(void)headerEndRefreshing;
//添加上拉刷新回調(diào)
-
(void)addFooterRefreshWithCallback:(void
(^)())callback;
//讓上拉刷新控件開始刷新
-
(void)footerBeginRefreshing;
//讓上拉刷新控件停止刷新
-
(void)footerEndRefreshing;
@end
/***
分割線
***/
#import
"UIScrollView+HWRefresh.h"
#import
"HWRefreshHeader.h"
#import
"HWRefreshFooter.h"
#import
<objc/runtime.h>
@interface
UIScrollView
()
@property
(nonatomic,
weak)
HWRefreshHeader
*header;
@property
(weak,
nonatomic)
HWRefreshFooter
*footer;
@end
@implementation
UIScrollView
(HWRefresh)
static
char
HWRefreshHeaderKey;
static
char
HWRefreshFooterKey;
-
(void)setHeader:(HWRefreshHeader
*)header
{
[self
willChangeValueForKey:@"HWRefreshHeaderKey"];
objc_s
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年廣西自然資源職業(yè)技術(shù)學(xué)院高職單招高職單招英語(yǔ)2016-2024歷年頻考點(diǎn)試題含答案解析
- 暗物質(zhì)與黑洞關(guān)系解析-深度研究
- 2025年廣州珠江職業(yè)技術(shù)學(xué)院高職單招數(shù)學(xué)歷年(2016-2024)頻考點(diǎn)試題含答案解析
- 區(qū)塊鏈技術(shù)在計(jì)算機(jī)歷史中的創(chuàng)新應(yīng)用-深度研究
- 2025年廣東交通職業(yè)技術(shù)學(xué)院高職單招語(yǔ)文2018-2024歷年參考題庫(kù)頻考點(diǎn)含答案解析
- 2025年川南幼兒師范高等??茖W(xué)校高職單招職業(yè)適應(yīng)性測(cè)試近5年??及鎱⒖碱}庫(kù)含答案解析
- 考慮制造商過度自信的雙渠道閉環(huán)供應(yīng)鏈回收模式選擇及協(xié)調(diào)研究
- 廠房吊車梁施工方案
- 磚混結(jié)構(gòu)住宅施工方案
- 玩具店施工方案
- DL-T-1642-2016環(huán)形混凝土電桿用腳扣
- 平安產(chǎn)險(xiǎn)陜西省地方財(cái)政生豬價(jià)格保險(xiǎn)條款
- 銅礦成礦作用與地質(zhì)環(huán)境分析
- 30題紀(jì)檢監(jiān)察位崗位常見面試問題含HR問題考察點(diǎn)及參考回答
- 詢價(jià)函模板(非常詳盡)
- 《AI營(yíng)銷畫布:數(shù)字化營(yíng)銷的落地與實(shí)戰(zhàn)》
- 麻醉藥品、精神藥品、放射性藥品、醫(yī)療用毒性藥品及藥品類易制毒化學(xué)品等特殊管理藥品的使用與管理規(guī)章制度
- 一個(gè)28歲的漂亮小媳婦在某公司打工-被老板看上之后
- 乘務(wù)培訓(xùn)4有限時(shí)間水上迫降
- 2023年低年級(jí)寫話教學(xué)評(píng)語(yǔ)方法(五篇)
- DB22T 1655-2012結(jié)直腸外科術(shù)前腸道準(zhǔn)備技術(shù)要求
評(píng)論
0/150
提交評(píng)論