不借助第三方插件利用ScrollView自身delegate實現下拉刷新和上拉加載
來源:程序員人生 發布時間:2015-06-01 08:46:05 閱讀次數:4339次
下拉刷新功能基本上在所有的app中都會被用到,而且這個功能已被apple集成進去了,不過必須得是在tableViewController中才有,是1個叫做UIRefreshControl的控件,想看效果可以看手機QQ上面聯系人列表下拉后的刷新。這里不多介紹。
本篇blog主要介紹如何在scrollview中實現下拉刷新的效果。由于有些時候我們可能更多地希望直接在scrollview中展現,而不是1定要局限于tableviewcontroller。
固然網上有很多下拉刷新和上拉加載的第3方控件,但是我這個人還是喜歡用系統原生API自己來做,1方面更能把原理吃透,另外一方面方便自己定義。
好了,空話不多說了,直接上代碼:
準備工作:
// 設置下拉刷新的process和label
self.indicatorView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(self.frame.size.width/2 - 50, ⑵5, 20, 20)];
[self.indicatorView setColor:[UIColor blackColor]];
self.pullRefreshLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.size.width/2 ⑵0, ⑶0, 90, 30)];
self.pullRefreshLabel.font = [UIFont fontWithName:@"heiti SC" size:14];
[self.pullRefreshLabel setText:@"下拉刷新"];
[self.scroll_view addSubview:self.indicatorView];
[self.scroll_view addSubview:self.pullRefreshLabel];
[self.scroll_view bringSubviewToFront:self.indicatorView];
[self.scroll_view bringSubviewToFront:self.pullRefreshLabel];
這里的準備工作其實就是在scrollview里面先加入1個activityIndicator和1個label
下拉刷新
// 下拉刷新
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
if (scrollView.contentOffset.y < ⑸0 ) {
[UIView animateWithDuration:1.0 animations:^{
// frame產生偏移,距離頂部50的距離(可自行設定)
[scrollView setContentInset:UIEdgeInsetsMake(30, 0, 0, 0)];
[self.indicatorView startAnimating];
} completion:^(BOOL finished) {
// 發起網絡要求
...
[self.indicatorView stopAnimating];
[self.pullRefreshLabel setText:@"下拉刷新"];
[scrollView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
// 將當前頁面置為1
currentPage = 1;
}];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
// 保持indecator的位置1直在頂端
if( scrollView.contentOffset.y < ⑸0){
[self.pullRefreshLabel setText:@"松開刷新"];
self.indicatorView.frame = CGRectMake(self.frame.size.width/2⑸0, scrollView.contentOffset.y+20 ,30, 30);
self.pullRefreshLabel.frame = CGRectMake(self.frame.size.width/2⑵0, scrollView.contentOffset.y+20, 100, 30);
}else{
self.indicatorView.frame = CGRectMake(self.frame.size.width/2⑸0, ⑶0 ,30, 30);
self.pullRefreshLabel.frame = CGRectMake(self.frame.size.width/2⑵0, ⑶0, 100, 30);
}
}
注意兩個代理不要用錯了。1個是WillBeginDecelerating ,1個是didScroll
willBeginDecelerating就是我們往下拉scrollview然后松手的時候,這個代理方法會去檢測當前scrollview的contentoffset,然后根據下拉的程度決定是不是進行刷新操作。這里我定義的閾值是50
然后為了使提示刷新的label和activityIndicator保持在1個固定的高度,就是不隨著scrollview的往下拉而1直往下走,在didScroll代理里面計算了1下它們的位置。
上拉加載:
/ 上拉繼續獲得
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
/*
* 關鍵-->
* scrollView1開始其實不存在偏移量,但是會設定contentSize的大小,所以contentSize.height永久都會比contentOffset.y高1個手機屏幕的
* 高度;上拉加載的效果就是每次滑動到底部時,再往上拉的時候要求更多,那個時候產生的偏移量,就可以讓contentOffset.y + 手機屏幕尺寸高大于這
* 個轉動視圖的contentSize.height
*/
if (scrollView.contentOffset.y + scrollView.frame.size.height >= scrollView.contentSize.height+50) {
// [UIView commitAnimations];
[UIView animateWithDuration:1.0 animations:^{
// frame產生的偏移量,距離底部往上提高50(可自行設定)
scrollView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
} completion:^(BOOL finished) {
scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
// 發送網絡要求
currentPage ++;
...
}];
}
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈