MJRefresh上拉下刷新的基本原理

狀態(tài)

Idle 閑置狀態(tài)

pulling 松開就可以進行刷新的狀態(tài)

refreshing 正在刷新狀態(tài)

初始狀態(tài):


header:Idle

footer:Idle

header的狀態(tài)變化

header在拖動中顯示出來:


拖拽下拉時使header開始出現(xiàn)在屏幕上

header開始出現(xiàn) -> header完全出現(xiàn)在屏幕上:Idle -> Pulling

header完全出現(xiàn) -> header部分出現(xiàn)在屏幕上:Pulling -> Idle

拖曳結(jié)束時(松手時):


這時是在Pulling狀態(tài)松手触创,所以狀態(tài)由:Pulling -> Refreshing

如果是在Idle狀態(tài)下松手急鳄,狀態(tài)不改變刘急。

footer的狀態(tài)變化


將要出現(xiàn)footer锚烦,此時footer狀態(tài)為Idle

footer由開始出現(xiàn) -> footer完全出現(xiàn):Idle -> Pulling

footer由完全出現(xiàn) -> footer部分出現(xiàn):Pulling -> Idle

拖曳結(jié)束時(松手時):


這是在Pulling狀態(tài)下松的手守伸,所以狀態(tài)由:Pulling -> Refreshing

如果是在Idle狀態(tài)下松的手,狀態(tài)不變。

header和footer的實現(xiàn)

初始位置確定:

從原始狀態(tài)可以看出:

header是scrollView的subView累盗,它的frame.y為-header.frame.height害淤。

footer也是scrollView的subView觉增,它的frame.y分為兩種情況:

當(dāng)contentSize.height > scrollView.frame.height時,footer.frame.y為contentSize.height

當(dāng)contentSize.height < scrollView.frame.height時斋陪,footer.frame.y為scrollView.frame.height

總而言之footer一定在scrollView的下方。

上面是最簡單的情況分析,可是現(xiàn)實中往往是下面這樣:

以上的示意圖可以設(shè)想一下属桦,一個tableViewController嵌入在navigationController中,navigationController又嵌入在tabbarController中他爸。此時tableViewController的tableView的contentInset屬性為(64,0,49,0)聂宾,contentOffset為(0,-64)。64是狀態(tài)欄加導(dǎo)航欄的高度诊笤,49是tabbar的高度系谐。這是tableViewController默認(rèn)設(shè)的一些值。

因此添加footer時要考慮oringinalInsets讨跟,把

當(dāng)contentSize.height < scrollView.frame.height時纪他,footer.frame.y為scrollView.frame.height

改為:

當(dāng)contentSize.height < scrollView.frame.height時,footer.frame.y為scrollView.frame.height - originalInsets.top - originalInsets.bottom

下面臨界值的確定都要考慮originalInsets

臨界值確定

確定了初始的位置后晾匠,要確定狀態(tài)之間變換的臨界線茶袒,通過KVO,監(jiān)聽scrollView的contentOffset的變化凉馆。

header臨界值:

contentOffset.y < -originalInsets.top時薪寓,才開始顯示header

contentOffset.y <= -originalInsets.top - header.frame.size.height時,才完全顯示header

footer的臨界值:

當(dāng)contentSize.height大于showHeight時:

contentOffset.y > scrollView.frame.size.height - showHeight - originalInsets.top時才開始顯示footer澜共。

contentOffset.y > scrollView.frame.size.height - showHeight - originalInsets.top + footer.frame.size.height時才完全顯示footer

當(dāng)contentSize.height小于showHeight時:

contentOffset.y > -originalInsets.top時就開始顯示footer向叉。

contentOffset.y > -originalInsets.top + footer.frame.size.height時才完全顯示footer。

懸浮狀態(tài)的實現(xiàn)

header的懸浮

1

2scrollView.contentInsets.top?=?header.frame.size.height?+?originalInsets.top

scrollView.contentOffset.y?=?-?(scrollView.contentInsets.top)

header的隱藏

1

2scrollView.contentInset.top?=?originalInsets.top

scrollView.contentOffset.y?=?-(scrollView.contentInsets.top)

footer的懸浮

當(dāng)contentSize.height大于showHeight時:



1scrollView.contentInsets.bottom?=?footer.frame.size.height?+?originalInsets.bottom

2scrollView.contentOffset.y?=?contentSize.height?-?showHeight?-?originalInsets.top?+?footer.frame.size.height

當(dāng)contentSize.height小于showHeight時:


scrollView.contentInsets.bottom?=?bottom?+?showHeight?-?contentSize.height

可以理解成初始的contentOffset.y為-originalInsets.top嗦董,然后向上移動了footer.frame.size.height:


scrollView.contentOffset.y?=?-originalInsets.top?+?footer.frame.size.height

footer的隱藏

scrollVIew.contentInsets.bottom?=?originalInsets.bottom

當(dāng)contentSize.height > showHeight時:

scrollView.contentOffset.y?=?contentSize.height?-?showHeight?-?originalInsets.top

當(dāng)contentSize.height < showHeight時:

scrollView.conentOffset.y?=?-originalInsets.top

UIScrollView屬性詳解:

坐標(biāo)系正方向:



ContentOffset的表示:



ContentInsets的表示:

contentInsets并不影響contentSize:



contentInsets影響contentOffset:



上圖的contentOffset為

(-contentInsets.left,?-contentInsets.top)


上圖的contentOffset為

(contentSize.width?-?scrollView.frame.size.width?+?contentInsets.right,?contentSize.height?-?scrollView.frame.size.height?+?contentInsets.bottom)

其實contentInsets就是為scrollView提供了更多的可停留空間母谎,切記要把彈簧效果開啟,否則在contentSize小于scrollView.frame時scrollView無法拉動京革。


scrollView.alwaysBounceVertical?=?YES;

self.scrollView.alwaysBounceHorizontal?=?YES;

在沒有設(shè)置contentInsets的情況下奇唤,scrollView的停留范圍為:


contentOffset.x:?0?->?max(contentSize.width?-?scrollView.frame.width,?0)

contentOffset.y:?0?->?max(contentSize.height?-?scrollView.frame.height,?0)

在有contentInsets的情況下供璧,scrollView的停留范圍為:


contentOffset.x:?-contentInsets.left?->?max(contentSIze.width?-?scrollView.frame.size.width)?+?contentInsets.right

contentOffset.y:?-contentInsets.top?->?max(contentSIze.height?-?scrollView.frame.size.height)?+?contentInsets.bottom

demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市冻记,隨后出現(xiàn)的幾起案子睡毒,更是在濱河造成了極大的恐慌,老刑警劉巖冗栗,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件演顾,死亡現(xiàn)場離奇詭異,居然都是意外死亡隅居,警方通過查閱死者的電腦和手機钠至,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胎源,“玉大人棉钧,你說我怎么就攤上這事√樵椋” “怎么了宪卿?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長万栅。 經(jīng)常有香客問我佑钾,道長,這世上最難降的妖魔是什么烦粒? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任休溶,我火速辦了婚禮,結(jié)果婚禮上扰她,老公的妹妹穿的比我還像新娘兽掰。我一直安慰自己,他們只是感情好徒役,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布孽尽。 她就那樣靜靜地躺著,像睡著了一般廉涕。 火紅的嫁衣襯著肌膚如雪泻云。 梳的紋絲不亂的頭發(fā)上艇拍,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天狐蜕,我揣著相機與錄音,去河邊找鬼卸夕。 笑死层释,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的快集。 我是一名探鬼主播贡羔,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼廉白,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乖寒?” 一聲冷哼從身側(cè)響起猴蹂,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎楣嘁,沒想到半個月后磅轻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡逐虚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年聋溜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叭爱。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡撮躁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出买雾,到底是詐尸還是另有隱情把曼,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布漓穿,位于F島的核電站祝迂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏器净。R本人自食惡果不足惜型雳,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望山害。 院中可真熱鬧纠俭,春花似錦、人聲如沸浪慌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽权纤。三九已至钓简,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汹想,已是汗流浹背外邓。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留古掏,地道東北人损话。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親丧枪。 傳聞我的和親對象是個殘疾皇子光涂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • MJRefresh是李明杰老師的作品,到現(xiàn)在已經(jīng)有9800多顆star了拧烦,是一個簡單實用忘闻,功能強大的iOS下拉刷新...
    Style_mao閱讀 660評論 1 2
  • 實現(xiàn)原理在tableView上加上一個View,注意不是headerView恋博,而是一個Y值為負數(shù)的普通View服赎,下...
    ScaryMonsterLyn閱讀 730評論 0 2
  • http://blog.csdn.net/cyuyanenen/article/details/52096134 ...
    大白頭閱讀 1,847評論 0 2
  • 時至“雙節(jié)”來臨重虑,為推動三思鄉(xiāng)教育工作健康有序發(fā)展,喜迎“十九大”勝利召開秦士,按照南和縣教育局領(lǐng)導(dǎo)要求缺厉,現(xiàn)將當(dāng)前工作...
    河北南和劉志玉閱讀 377評論 1 2
  • 我們每天起床、洗漱隧土、吃飯提针、睡覺,中間除了工作的必要時間曹傀,其余都是如何度過的呢辐脖,別小看這些時間它足以拉開人與人之間的...
    上鋪的知乎菌閱讀 234評論 0 0