UIView只收集move軌跡,不接收“單擊”、“長按”事件

來源:互聯網
上載者:User

參考:

[1]http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MultitouchEvents/MultitouchEvents.html#//apple_ref/doc/uid/TP40009541-CH3-SW20

情景:

如果你有一個全屏、透明的UIView蓋在目前介面的上面,這個uivew不做顯示用,只是收集使用者在螢幕上的move 時的點。但要允許使用者在點擊和長按時,全屏view背後的view做出反應,這時全屏的view相當於不存在。

解決方案:

方案一

設定該全屏、透明view的 userInteractionEnabled 為NO,截獲UIApplication的SendEvent ,在其中記錄move時的所有點。這時,使用者所有的touch事件都按原來執行,這個全屏的view真像不存在一樣。

利用objective-c runtime相關代碼核心實現如下:

    //Swap the implementations of our interceptor and the original sendEvent:    Method oldMethod = class_getInstanceMethod(self, @selector(sendEvent:));    Method newMethod = class_getInstanceMethod(self, @selector(interceptSendEvent:));    method_exchangeImplementations(oldMethod, newMethod);

簡單的說就是建立一個UIApplication的類別,然後通過method_exchangeImplementations 替換sendEvent,讓系統調用sendEvent時首先調用我們自己定義的方法,然後在其中記錄move的point點,最後調用系統原來的sendEvent方法即可。

方案二

設定該全屏、透明view的 userInteractionEnabled 為YES,重寫父類的四個事件處理方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)forwardTouchBegan:(id)obj{NSArray* array = (NSArray*)obj;NSSet*   touches = [array objectAtIndex:0];UIEvent* event   = [array objectAtIndex:1];[[self nextResponder] touchesBegan:touches withEvent:event];}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{touchMove_ = NO;[self performSelector:@selector(forwardTouchBegan:) withObject:[NSArray arrayWithObjects:touches,event,nil] afterDelay:0.5];}- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{touchMove_ = YES;[[self class] cancelPreviousPerformRequestsWithTarget:self];}- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{if (!touchMove_){[[self nextResponder] touchesEnded:touches withEvent:event];}}

這裡主要應用了這兩個方法,在begin時延時調用forwardTouchBegan ,在move時取消 調用。這裡用延時方法有效地解決了 無法判斷使用者touch begin時接下去是否會move的問題。參考【1】中列出了蘋果文檔中利用此方法來解決
單擊還是雙擊的問題,只不過這時在touch end啟動延時調用performSelector ,在touch begin時根據tapcount判斷是否取消調用。

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;

+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget;

不過方案二 跟 背景view與全屏viewview層次相關,如果兩則不同的window 則  通過[self nextResponder] 背景view可能還是接收不到事件。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.