iOS下點選任意空白Dismiss當前自定義的AlertView

發表於2015-04-17

iOS下原生的UIAlertView/UIActionSheet/UIAlertController有時候無法滿足我們的需求,我們就會自定義一些彈出框。一般的自定義方案通常是定義一個UIView或者UIView的子類,然後在上面新增一些元件,最後新增到我們指定的parentView上,中間可能還會加幾個比較炫酷的動畫,這樣就達到了我們某些彈出框或者選單的效果。問題出在如果我們新增到某個View上,但是該View不是全屏的View,我們點選某些地方可能就無法獲取到觸控事件,我們的選單就無法得到響應。

我們定義選單的時候一般會設計如下所示的兩個方法:

- (NSInteger)showInView:(UIView *)view animated:(BOOL)animated;
- (void)dismissAnimated:(BOOL)animated

每當我們需要展示選單的時候,我們就呼叫showInView:方法,把選單新增到view上,反之,當選單需要結束的時候,就會被dismiss。

之前也有一篇自定義選單的文章:Block程式碼繼續執行的AlertView,當時的重點不在於介紹AlertView,大家可以下載體驗下。

很多時候我們設計的選單都是非阻塞使用者操作的,意思就是點選空白的時候,不能因為有選單,而影響使用者的操作,至少是點選空白的時候,要將選單消失掉。當我們的view不是全屏的時候,我們如何能做到點選view區域外面還能dismiss當前的選單呢?

之前的文章介紹過iOS的事件分發模組,大家可以檢視之前的部落格get這些知識,HitTest其實是給View第一次機會,去處理一些東西。有一點值得肯定的是,如果touchEvent發生在View’s的frame之外,則該View無法檢測到這個touchEvent。所以我們要想實現部落格所描述的功能,我們只能依賴於新插入的View。思路很簡單,每次選單展示的時候,插入一個透明的View到當前的window上,抓住hitTest給的這次機會,去根據當前情況分發事件。

1、如果點選區域在選單內,則把事件分發給選單

2、否則則直接dismiss掉選單

這裡提供一些簡單的事件分發程式碼,以供大家參考

然後在show的時候,將self.hitTestView新增到window上,dismiss的時候,從window移除。

這樣,就實現了我們的需求,思路比較簡單,就是在window的最頂層新增一個View用於檢測觸控事件,當檢測到事件之後,根據當前條件來處理事件。

大家可以去我的github下載STKitDemo,裡面有STAlertView的相關的實現,使用方式在元件->檢視大圖->選單中可以看到。

相關文章