取消UIScrollView的慣性滑動(dòng)

產(chǎn)品經(jīng)理說按照某團(tuán)、某東、某寶的效果實(shí)現(xiàn)。我X,我要是能一模一樣的實(shí)現(xiàn)別人的效果你覺得我還會(huì)待在這里嗎?

通常,需求確定下來,UI出圖之后看到稍微復(fù)雜的頁面后會(huì)先到簡(jiǎn)書、GitHub、cocoaChina上面去找有沒有。如果有直接照搬過來,如果沒有就有點(diǎn)懵逼了,為什么會(huì)這樣?還是基礎(chǔ)知識(shí)不扎實(shí),技術(shù)不夠呀!那該怎么辦?平常多思考、多積累唄,不要僅僅當(dāng)一個(gè)代碼搬運(yùn)工,沒有前途??!言歸正傳!


UIScrollView其實(shí)是沒有設(shè)置慣性這個(gè)屬性的,只能通過代理方法監(jiān)聽滾動(dòng)的過程,來達(dá)到控制慣性的目的。


控制tableView的滑動(dòng),類似美團(tuán)-美食中的地圖列表

首先要明確,通過[scrollView setContentOffset:CGPointZero animated:NO];這個(gè)方法設(shè)置UIScrollView的偏移,是不會(huì)觸發(fā)UIScrollView的- (void)scrollViewDidScroll:(UIScrollView*)scrollView這個(gè)代理方法的。

接下來看一下怎么通過UIScrollView的代理方法達(dá)到取消慣性

1、當(dāng)手指放在屏幕開始拖動(dòng)前,會(huì)先調(diào)用下面的代理方法

- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView {

? ? ? lastContentOffset = scrollView.contentOffset.y;//用來判斷滾動(dòng)方向

}

2、滾動(dòng)中會(huì)調(diào)用下面的代理方法

- (void)scrollViewDidScroll:(UIScrollView*)scrollView {

//可以再這個(gè)方法里面動(dòng)態(tài)控制某個(gè)控件的隱藏、透明度以及跟隨UIScrollView的偏移而變化位置

? ? ? CGFloatoffsetY? = scrollView.contentOffset.y;

if (offsetY < self.lastContentOffset){//向下滾動(dòng)

? ? } else if (offsetY >self.lastContentOffset) {//向上滾動(dòng)

? ? }

}

3、這個(gè)是控制慣性滑動(dòng)的重要方法,手指將要松開時(shí)調(diào)用

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inoutCGPoint *)targetContentOffset

{

? ? CGFloat speed = fabs(velocity.y);//滾動(dòng)速度的絕對(duì)值,也可以根據(jù)velocity.y的正負(fù)判讀滾動(dòng)方向 假如為0 說明手動(dòng)拖動(dòng)停止 沒有慣性滑動(dòng)

? ? CGFloat offsetY = scrollView.contentOffset.y;

? ? CGFloat maxSpeed =2.7;//超過這個(gè)最大速度要做的操作

? ? if( velocity.y <0) {//向下滑動(dòng)

? ? ? ? if(speed > maxSpeed && offsetY >0) {//頂部往下滑

? ? ? ? ? ?[self performSelectorOnMainThread:@selector(stopOnTop:) withObject:scrollView waitUntilDone:NO];//一定要在主線程立即執(zhí)行 和 runLoop有關(guān)

? ? ? ? }

? ? }

? ? else {//向上滑動(dòng)

? ? }

}

- (void)stopOnTop:(UIScrollView *)scrollView {//在頂部停止?jié)L動(dòng)

? ? [self.tableView setContentOffset:CGPointZero animated:YES];

}

4、手指已經(jīng)松開會(huì)調(diào)用這個(gè)代理方法

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {//decelerate為YES 說明有滑動(dòng) NO沒有滑動(dòng) 直接停止

if (!decelerate) {//手指控制 直接停止 也就是拖動(dòng)一段距離直接停止

? ? ? ? BOOLdragToDragStop = scrollView.tracking && !scrollView.dragging && !scrollView.decelerating;

? ? ? ? if(dragToDragStop) {// 停止后要執(zhí)行的代碼

? ? ? ? ? ? [self scrollViewEndScroll:scrollView];

? ? ? ? }

? ? }

}

5、減速結(jié)束會(huì)調(diào)用這個(gè)方法,并不是就一定等于滑動(dòng)結(jié)束了。因?yàn)橛行┗瑒?dòng)并不需要減速也可以結(jié)束,比如我兩只手輪流向左滑動(dòng),直到滑動(dòng)到scrollview的右側(cè)盡頭為止,這個(gè)過程的滑動(dòng)是被迫終止而不是自然減速停止,這樣scrollViewDidEndDecelerating方法是不會(huì)被執(zhí)行的

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

BOOLscrollToScrollStop = !scrollView.tracking && !scrollView.dragging && !scrollView.decelerating;//為YES 表示滾動(dòng)結(jié)束

? ? if(scrollToScrollStop) {// 停止后要執(zhí)行的代碼

? ? ? [self scrollViewEndScroll:scrollView];

? ? }

}

- (void)scrollViewEndScroll:(UIScrollView *)scrollView { //完全停止?jié)L動(dòng)要做的處理

}


ScrollView一次拖拽的代理方法執(zhí)行流程

以上代理方法,只有真正理解后才能很好的處理跟ScrollView滾動(dòng)相關(guān)的事件!


下面補(bǔ)充一些小的知識(shí)點(diǎn)

self.tableView.decelerationRate = UIScrollViewDecelerationRateFast; ? ?//這個(gè)屬性用來調(diào)節(jié)scrollView的滾動(dòng)速度

? ? ?int abs(int i);? ? ? ? ? ? ? ? ? //處理int類型的取絕對(duì)值

?? ? double fabs(double i);//處理double類型的取絕對(duì)值

?? ? float fabsf(float i);? ? ? ? ? /處理float類型的取絕對(duì)值

self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(- 104, 0, 0, 0);//設(shè)置滾動(dòng)條的偏移量,如果發(fā)現(xiàn)豎向滾動(dòng)條錯(cuò)亂,一般和scrollView的automaticallyAdjustsScrollViewInsets 屬性有關(guān),設(shè)置為NO即可


參考資料:

https://tech.glowing.com/cn/practice-in-uiscrollview/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容