iOS 不規則Button點擊(一)

需求

利用圖片,實現一個如圖的按鈕組。git

遇到的問題

以下圖所示:github

  • 功能一、二、三、4的按鈕能夠實現點擊功能。可是在紅色方框四角的位置,也會響應相應的點擊事件。
  • 紫色方框內四角區域點擊時,響應的方法是功能5,而不是對應的功能。

解決思路

指望的結果

  • 尋找到合適的Button來處理點擊事件

須要弄明白的問題

  • 事件在如何傳遞的?
  • 怎麼判斷誰來處理當前事件?

事件是如何傳遞的?數組

  1. 當用戶觸摸實際屏幕時,會生成一個Touch Event,將此事件添加到UIApplication管理的事件隊列之中。
  2. UIApplication從事件隊列之中按順序取出事件分發到視圖去處理。
  3. 當事件被髮出之後,會從keyWindow開始,依次向上傳遞,包括Controller以及View,最後找到合適的視圖來響應事件。

能夠看出:當一個事件發生後,事件會從父控件傳給子控件,也就是說由UIApplication -> UIWindow -> UIView -> initial view,以上就是事件的傳遞,也就是尋找最合適的view的過程。bash

涉及到兩個方法:ide

func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
func point(inside point: CGPoint, with event: UIEvent?) -> Bool
複製代碼

當UIApplication發送事件到keyWindow時,會調用 hitTest來尋找最合適的視圖處理事件。判斷邏輯以下:post

  1. 首先判斷自身是否可以響應觸摸事件(userInteractionEnabled==true、hidden==true、alpha<=0.01不能響應觸摸事件),若能響應則下一步,不然返回nil。spa

  2. 若是能夠響應觸摸事件,調用pointInside來判斷是否在顯示區域內,若是不在其中,pointInside返回false,同時hitTest返回nil。code

  3. 若是 pointInside返回true,表示在當前的視圖之中,而後倒序遍歷該視圖的子視圖,重複上述步驟,直到某一視圖能夠響應,hitTest:返回該視圖。cdn

  4. 若是執行完上述步驟之後,沒有符合條件的視圖響應事件,則返回視圖自己,表示只有當前視圖符合條件,可以處理該事件。blog

    Q:爲何倒序遍歷?
     A:由於在subViews數組中,最後添加的視圖,在視圖層級中處於最上方。
    複製代碼

怎麼判斷誰來處理當前事件?

當知道的上面事件傳遞機制後,咱們就能理清楚咱們的Button處理事件的邏輯了:

  1. 自定義Button繼承自系統的Button。

  2. 重寫 point(inside point: CGPoint, with event: UIEvent?) -> Bool 方法。在其中判斷當前事件是否須要自身處理。

    • 判斷點是否在自身button.imageView的frame範圍內
    • 獲得點擊點在button.imageView中該點的顏色值
    • 若是獲得的色值中alpha小於閥值,則返回false

具體代碼能夠查看JTShapedButton源碼

實現效果

後記

這裏記錄的不規則按鈕是在設置圖片狀況下的。

還有另外一種狀況是:按鈕的形狀是本身繪製的,這種狀況的處理能夠看另外一篇文章iOS 不規則Button點擊(二)

相關文章
相關標籤/搜索