自定義下拉重新整理控制項

2021-09-08 19:45:08 字數 4171 閱讀 4390

一:前言

二: 了解 uirefreshcontrol

//初始化乙個control

uirefreshcontrol *control = [[uirefreshcontrol alloc] init];

//給control 新增乙個重新整理方法

[control addtarget:self action:@selector(refreshaction) forcontrolevents:uicontroleventvaluechanged];

//把control 新增到 tableview

[self.tableview addsubview:control];

經過多次反覆測試,下拉的偏移量達到130以上才會觸發重新整理方法,很顯然這個也不符合,一般的重新整理控制項的高度60左右,所以下拉的偏移量達到60就可以觸發重新整理的方法了。

去掉預設的動畫效果

自定義自己的動畫效果

改變滿足重新整理時的條件

三:fmrefreshcontrol

fmrefreshcontrol *control = [[fmrefreshcontrol alloc] initwithtargrt:self refreshaction:@selector(refreshaction)];

[self.tableview addsubview:control];

兩行**,用法比系統的還要稍微簡單一點。

四:思路與**

1. 關於 uirefreshcontrol 的幾個注意點,通過frame無法修改它的高度,修改高度目前只找到一種方法,先新增到 superviwe,再執行

[[_control.subviews objectatindex:0] setframe:cgrectmake(0, 0, _control.bounds.size.width, 30)];

一開始我是想改變它的高度是否就能改變它的觸發重新整理的偏移量,然後我找到了這個方法可以修改它的高度,但實際上改變了高度還是無法改變觸發下拉重新整理的偏移量,所以我們需要自定義去觸發重新整理這個動作的時機。

2.手動去觸發重新整理動作也有幾個注意點,我們是根據偏移量去觸發重新整理,但是僅僅靠這乙個動作是不夠的,還需要乙個條件,那就是使用者手指響應過螢幕,簡單地說,先定義乙個變數,如果使用者觸控過螢幕,就把變數置為yes,然後再判斷使用者手指離開時是否達到了觸發重新整理的偏移量,如果兩個條件都滿足,就觸發重新整理,重新整理完把變數置為no,如果不滿足,就不觸發,也把變數置為no。這樣就避免了uiscrollow 因偏移量變動而導致非人為的重新整理。

3. 進入**階段

fmrefreshcontrol *control = [[fmrefreshcontrol alloc] initwithtargrt:self refreshaction:@selector(refreshaction)];

[self.tableview addsubview:control];

初始化的時候賦乙個 target 和 乙個 action,當滿足條件的時候,我們需要知道讓誰去執行重新整理方法,有這兩個引數足夠,當執行到第二行 addsubview的時候,我們需要在control內部實現這個方法:

- (void)willmovetosuperview:(uiview *)newsuperview else if (self.currentstatus == fmrefreshstatenormal && self.superscrollview.contentoffset.y < normalpullingoffset) else if(!self.superscrollview.isdragging){

if (self.currentstatus == fmrefreshstatepulling) {

self.currentstatus = fmrefreshstaterefreshing;

//拖動的偏移量,轉換成正數

cgfloat pulldistance = -self.frame.origin.y;

self.backgroundview.frame = cgrectmake(0, 0, k_fmrefresh_width, pulldistance);

cgfloat totalwidth = 35 + 20 + self.label.bounds.size.width;

cgfloat imageviewx = (k_fmrefresh_width - totalwidth)/2;

self.imageview.frame = cgrectmake(imageviewx,  -k_fmrefresh_height+pulldistance+(k_fmrefresh_height - self.imageview.bounds.size.height)/2, self.imageview.frame.size.width, self.imageview.frame.size.height);

self.label.frame = cgrectmake(imageviewx + 35 + 20, -k_fmrefresh_height + pulldistance + (k_fmrefresh_height - self.label.bounds.size.height)/2, self.label.frame.size.width, self.label.frame.size.height);  

這裡最重要的就是處理兩點:1. 根據偏移量和使用者手指的拖動來切換狀態,2. control上面的子檢視需要我們根據偏移量來實時更新。

還有一種情況,上面也提到過,使用者先滑動到fmrefreshstatepulling狀態,然後又往回滑動,此時的偏移量在0-fmrefreshstatepulling狀態的偏移量之間,此時呼叫自身的 endrefreshing偏移量不會復原,還需要我們自己處理,看了幾個老外寫的自定義重新整理控制項,他們都沒修復這個bug。他們也沒封裝,全部**寫在了控制器裡,什麼都沒有改變,只是實現了乙個動畫效果,還多了個bug,動畫效果倒是不錯的。有興趣的可以參考一番:

- (void)endrefreshing {

if (self.currentstatus != fmrefreshstaterefreshing) {

return;

self.currentstatus = fmrefreshstatenormal;

[super endrefreshing];

//在執行重新整理的狀態中,使用者手動拖動到 nornal 狀態的 offset,[super endrefreshing] 無法回到初始位置,所以手動設定

dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(0.5 * nsec_per_sec)), dispatch_get_main_queue(), ^{

if(self.superscrollview.contentoffset.y >= self.originaloffsety - k_fmrefresh_height && self.superscrollview.contentoffset.y <= self.originaloffsety) {

cgpoint offset = self.superscrollview.contentoffset;

offset.y = self.originaloffsety;

[self.superscrollview setcontentoffset:offset animated:yes];

最後還有一點不要忘記 dealloc移除監聽:

- (void)dealloc {

[self.superscrollview removeobserver:self forkeypath:@"contentoffset"];

整篇文章從上至下是按照整個完整的思路寫下來的,先是提出遇到的問題以及難點,然後最後的**和思路也是由外至內一路寫下來,希望方便大家閱讀。這是上篇,下拉重新整理的,還有下篇,上拉載入,過兩天寫,demo中已經有了,不過就是還沒優化。

自定義下拉重新整理的listview

listview的下拉重新整理功能的實現依靠在listview前面加上頭布局,通過判斷頭布局的位置確實使用者是否下拉,然後根據情況進行處理 public class reflashlistview extends listview implements onscrolllistener public...

scroll view實現自定義下拉重新整理

refresher enabled true 開啟下拉重新整理 refresher triggered 設定當前下拉重新整理狀態,true 表示下拉重新整理已經被觸發,false 表示下拉重新整理未被觸發 bindrefresherrefresh 自定義下拉重新整理被觸發事件 bindscrollt...

iOS 自定義MJRefresh下拉重新整理動畫

實現如下 mjrefreshgifheader繼承自mj中的mjrefreshgifheader import mjrefreshgifheader.h inte ce customrefreshgifheader mjrefreshgifheader 設定state狀態下的動畫images 動畫持...