最近要做個信息登記界面,在scrollView中添加了多個button和一個自定義的view(畫板)來實現簽名效果,畫板中實現了touchBegin,touchMove等觸摸事件方法。為了使button能響應scrollView的滑動觸摸事件在網上找了很多資料,結果要么就是手指放在button上能滑動,但放在畫板上就不能畫畫或者能畫畫但button不能滑動,沒有兩全其美的方法,摸索了很久最終找到了解決方法。先看圖。
先說下常見的方法self.scrollView.panGestureRecognizer.delaysTouchesBegan = YES;
設置scrollView的延遲接收點擊觸摸事件,此時button能實現滑動和點擊效果,但由于畫板需要接收點擊觸摸事件才能開始畫,故需要先長按,達不到我們要的效果,故pass。
另外一種方法
self.scrollView.delaysContentTouches = YES;
此時畫板畫畫沒有延遲,但button無法識別滑動觸摸事件,滑動時會直接實現點擊。
解決方法
既要能實現button點擊效果,又要實現畫板畫畫無延遲,那么解決辦法來啦~
首先要設置scrollView的兩個屬性
self.scrollView.canCancelContentTouches = YES;
self.scrollView.delaysContentTouches = NO;
- delaysContentTouches表示scrollView的子控件響應觸摸事件是否有延遲,NO表示立即響應,YES表示延遲響應;
- canCancelContentTouches與delaysContentTouches相反,假如你設置canCancelContentTouches為YES,那么當你在UIScrollView上面放置任何子視圖的時候,在子視圖上移動手指的時候,UIScrollView會給子視圖發送touchCancel的消息,既不響應觸摸事件。而如果該屬性設置為NO,ScrollView本身不 處理這個消息,全部交給子視圖處理。
接著創建一個scrollView的分類,實現兩個與上面屬性配套的方法
#import "MainScrollView.h"
#import "HBSignView.h" //自定義的view,實現畫板功能
@implementation MainScrollView
//當設置canCancelContentTouches=YES時,觸摸事件響應前會調用該方法
-(BOOL)touchesShouldCancelInContentView:(UIView *)view{
if ([view isKindOfClass:[UIButton class]]) {
return YES;
}
return [super touchesShouldCancelInContentView:view];
}
//在觸摸事件開始相應前調用
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
if ([view isKindOfClass:[HBSignView class]]||[view isKindOfClass:[UIButton class]]) {
return YES;
}
return NO;
}
當設置canCancelContentTouches=YES時,除了touchBegin以外的所有觸摸事件響應前會調用touchesShouldCancelInContentView:
返回YES表示子視圖不響應觸摸事件,返回NO表示由子視圖來處理觸摸事件。而touchesShouldBegin:withEvent:inContentView:
在每次觸摸事件開始前都會調用,而且先于touchesShouldCancelInContentView:
于是先在touchesShouldBegin:withEvent:inContentView:
判斷當子視圖是button或者是畫板時,就由子視圖自己處理觸摸事件;接著在touchesShouldCancelInContentView:
方法中,判斷子視圖是否是button,如果是則讓其不響應觸摸事件,由此過濾掉除了點擊以外的所有觸摸事件
demo請點擊SimonDeCft