一,
公司的項目 遇到的問題 ,解決的方法,
UIButton 不響應或延遲響應 UIControlEventTouchDown 事件的解決辦法
UIControlEventTouchDown即按鈕按下時應觸發的方法。實際使用過程中會出現延遲響應或間歇無響應,但是放開手指時會直接響應UIControlEventTouchDown、UIControlEventTouchUpInside兩個方法,這種情況下,按下按鈕不響應任何事件,當移動手指時會響應UIControlEventTouchDown。
1.延遲響應:
一般是因為button放在了UIScrollVIew或UITableView上面,按下按鈕時系統會判斷是不是滑動手勢。將UIScrollVIew的delaysContentTouches、 canCancelContentTouches 兩個屬性都設置為NO;
2.無響應:查到的資料,有人說“
UIControlEventTouchDown事件是一旦手指碰到按鈕就調用了,這樣在iOS7上會產生一個沖突,由于iOS7加上了手勢滑動返回這么一個動作,
在手勢滑動返回時那個區域是不允許有UIControlEventTouchDown事件的,不然就會有事件沖突了,系統不知道是要準備返回還是要點擊那個Button,
所以就加上了TouchDown事件的一個延遲響應。
解決方案
禁止所有滑動返回的手勢,讓TouchDown能夠正常響應 self.navigationController.interactivePopGestureRecognizer.delaysTouchesBegan=NO;
重寫UIButton,捕捉所有的手勢事件然后重寫”。
導航欄的側滑 事件;
重新的父類的手勢方法,直空。
二,IOS 手勢事件的沖突
關于手操作需要強調幾點:
UIImageView默認是不支持交互的,也就是userInteractionEnabled=NO ,因此要接收觸摸事件(手勢識別),必須設置userInteractionEnabled=YES(在iOS中UILabel、UIImageView的userInteractionEnabled默認都是NO,UIButton、UITextField、UIScrollView、UITableView等默認都是YES)。
輕掃手勢雖然是連續手勢但是它的操作事件只會在識別結束時調用一次,其他連續手勢都會調用多次,一般需要進行狀態判斷;此外輕掃手勢支持四個方向,但是如果要支持多個方向需要添加多個輕掃手勢。
手勢沖突
細心的童鞋會發現在上面的演示效果圖中當切換到下一張或者上一張圖片時并沒有輕掃圖片而是在空白地方輕掃完成,原因是如果我輕掃圖片會引起拖動手勢而不是輕掃手勢。換句話說,兩種手勢發生了沖突。
沖突的原因很簡單,拖動手勢的操作事件是在手勢的開始狀態(狀態1)識別執行的,而輕掃手勢的操作事件只有在手勢結束狀態(狀態3)才能執行,因此輕掃手勢就作為了犧牲品沒有被正確識別。我們理想的情況當然是如果在圖片上拖動就移動圖片,如果在圖片上輕掃就翻動圖片。如何解決這個沖突呢?
在iOS中,如果一個手勢A的識別部分是另一個手勢B的子部分時,默認情況下A就會先識別,B就無法識別了。要解決這個沖突可以利用- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;方法來完成。正是前面表格中UIGestureRecognizer的最后一個方法,這個方法可以指定某個手勢執行的前提是另一個手勢失敗才會識別執行。也就是說如果我們指定拖動手勢的執行前提為輕掃手勢失敗就可以了,這樣一來當我們手指輕輕滑動時系統會優先考慮輕掃手勢,如果最后發現該操作不是輕掃,那么就會執行拖動。只要將下面的代碼添加到添加手勢之后就能解決這個問題了(注意為了更加清晰的區分拖動和輕掃[模擬器中拖動稍微快一點就識別成了輕掃],這里將長按手勢的前提設置為拖動失敗,避免演示拖動時長按手勢會被識別):
//解決在圖片上滑動時拖動手勢和輕掃手勢的沖突
[panGesture requireGestureRecognizerToFail:swipeGestureToRight];
[panGesture requireGestureRecognizerToFail:swipeGestureToLeft];
//解決拖動和長按手勢之間的沖突
[longPressGesture requireGestureRecognizerToFail:panGesture];
兩個不同控件的手勢同時執行
我們知道在iOS的觸摸事件中,事件觸發是根據響應者鏈進行的,上層觸摸事件執行后就不再向下傳播。默認情況下手勢也是類似的,先識別的手勢會阻斷手勢識別操作繼續傳播。那么如何讓兩個有層次關系并且都添加了手勢的控件都能正確識別手勢呢?答案就是利用代理的-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer方法。這個代理方法默認返回NO,會阻斷繼續向下識別手勢,如果返回YES則可以繼續向下傳播識別
具體實現,首先添加UIGestureRecognizerDelegate協議,然后把 Tap手勢識別對象設置代理self,然后實現如下代碼:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UIButton class]]){
return NO;
}
return YES;
}