為什么按鈕高亮后不顯示高亮圖片

問題:

如果在UIScrollView的上面放置了一個按鈕,那么這個按鈕點擊的時候,按鈕的高亮狀態的圖片是不能顯示的。

原因:

這個由于UIScrollView和UIButton兩者的事件響應的沖突引起的。

解決方案:

這時候需要在UIScrollView的身上動手了,自定義一個CustomScrollView,重寫里面的touchesShouldCancelInContentView方法,然后用自定義的這個CustomScrollView,實例化后,設置其delaysContentTouches的值為false,這樣就解決了。

代碼:

class CustomScrollView:UIScrollView{
    override func touchesShouldCancelInContentView(view: UIView) -> Bool { 
       return true
    }
}

let scrollVeiw = CustomScrollView()
scrollVeiw.delaysContentTouches = false

原因進一步分析:

  • 1:因為scrollView有一個150ms的延時判斷,當我們的手指放在scrollView上時,如果在這150ms內我們的手指有移動,那么這是事件就會判斷為“拖動scrollView的事件”,就不會被傳遞給它的子控件了;如果在這150ms內手指沒有移動,則將這個touch事件傳遞給其最適合響應的子控件。那么顯然將這個延時判斷去除問題就顯然解決了(self.scrollVeiw.delaysContentTouches = false)。
  • 2:但是又會產生新的問題,就是當我們手指落在Button上時開始滑動scrollView,這時scrollView就不會滑動了。解決方案就是重寫scrollView的touchesShouldCancelInContentView方法,返回false。當UIScrollView將touch事件交給子view后,當手指發生滑動時,調用此方法,假如返回false,則將touch事件交給子view,如果返回false,則交給UIScrollView處理,產生滑動。

UIScrollView的工作原理:

UIScrollView的工作原理,當手指touch的時候,UIScrollView會攔截Event,會等待一段時間,在這段時間內,如果沒有手指沒有移動,當時間結束時,UIScrollView會發送tracking events到子視圖上。在時間結束前,手指發生了移動,那么UIScrollView就會進行移動,從而取消發送tracking。

用戶touch —> tracking真 —> 如果點擊一個可交互視圖上,判斷邏輯過程如下:

  • 步驟1:根據delaysContentTouches的值,判斷什么時候步驟2(立刻還是判斷一定條件);

  • 步驟2:調用touchesShouldBegin方法,如果返回值為yes,touch事件傳給子視圖;如果為no,touch事件不傳給子視圖,進入狀態n。(跳轉)

  • 步驟3:touch move的,
    3.1 如果canCancelContentTouches為no,不調用touchesShouldCancelInContentView方法,類也不scroll,進入狀態m;
    3.2 如果canCancelContentTouches為yes,調 用touchesShouldCancelInContentView,根據touchesShouldCancelInContentView方法的返回值;如果是yes,進入狀態s。如果是no,進入狀態m。

狀態n :tracking為真,如果touch move的就scroll,touch松開,進入狀態e
狀態s :touch move中,類scroll,如果touch松開,進入狀態e
狀態m:touch move中,類不scroll,如果touch松開,進入狀態e
狀態e : 結束

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容