1. 程式人生 > >UIScrollView上的UIButton,既能點選UIButton,又能滑動UIScrollView,但是點選UIButton時間短的話,不會高亮

UIScrollView上的UIButton,既能點選UIButton,又能滑動UIScrollView,但是點選UIButton時間短的話,不會高亮

最近做專案遇見一個問題:UIScrollView上有許多UIButton,要實現既能點選UIButton,又能滑動UIScrollView,這個實現沒有問題,不需要做額外的touch管理,UIScrollView能識別是點選的UIButton還是滑動本身,但是有一個效果上的問題,就是點選UIButton時間短的話,不會高亮,但是確實是觸發點選了,這樣就造成了假象,給人一種UIButton沒有被點選的感覺。如果點選時間長的話沒有問題,會高亮。

這麼看來,導致這樣現象應該就是時間長短的問題,順著這個問題想下去,就追尋到UIScrollView的touch原理,當UIScrollView接收到一個touch時,它會在一段時間(好像是150ms)內監聽該touch是否移動了,假如移動了(應該有一個移動範圍),則取消將touch傳送到其子檢視(例如UIButton),UIScrollView自身接受該touch,進行滑動。看來應該就是這段判斷時間惹的禍了(這裡其實我還想不明白為什麼明明點選了Button,也確實觸發了點選,卻沒有高亮狀態,哪位大神知道的話請指教),那要解決問題是不是就應該把這段時間取消掉呢,不要這個判斷時間,那麼UIButton應該就會立即響應併產生高亮狀態吧。正好UIScrollView中有一個屬性叫delaysContentTouches

,官方文件對它的解釋是:Ifthe value of this property is YES, the scroll view delays handlingthe touch-down gesture until it can determine if scrolling is theintent. If the value is NO , the scroll view immediately callstouchesShouldBegin:withEvent:inContentView:. The default value isYES.意思就是設定為NO就不會存在那個150ms的判斷時間了,直接執行後續操作。那麼咱們設定為NO來試試唄。結果確實如所想那樣,UIButton立即響應並高亮。

但是…..別高興太早,雖然這個問題解決了,但是新的麻煩又產生了,螳螂捕蟬黃雀在後!你會發現UIScrollView滑動不像以前那樣了,假如touchdown的那點落在UIButton上然後再滑動手指,UIScrollView不會滑動,但是UIButton仍然觸發,當然,這樣的結果也是應該的,你想想,設定delaysContentTouches為NO後,只要手指點在UIButton上,UIScrollView就會立即判定為這是點選UIButton,而不會再等待看手指是否移動來決定是否要滑動本身了。

那麼如何解決這個問題呢?你會想,有沒有什麼方法可以在touch到UIbutton上並滑動時不觸發UIButton而讓UIScrollView自己滑動呢,強大的iOS沒有讓你失望,UIScrollView中有一個方法:touchesShouldCancelInContentView

:,來看它的解釋:Thescroll view calls this method just after it starts sending trackingmessages to the content view. If it receives NO from this method,it stops dragging and forwards the touch events to the contentsubview. The scroll view does not call this method if the value ofthe canCancelContentTouches property isNO.意思就是當UIScrollView將touch事件交給子view後,當手指發生滑動時,呼叫此方法,假如返回NO,則將touch事件交給子view,如果返回YES,則交給UIScrollView處理,產生滑動。(但是前提是UIScrollView的canCancelContentTouches屬性是YES才會呼叫這個方法,只要不是UIControll的子類,這個屬性預設是YES。)所以只要重寫UIScrollView的這個方法並返回YES就可以啦,到此問題就解決了。既能立即響應UIButton,也能自由滑動UIScrollView。