使用 touches 方法來監(jiān)聽 view 的觸摸事件弊端:
- 必須得自定義 view, 在自定義的 View 當(dāng)中去實(shí)現(xiàn) touches 方法
- 由于是在 view 內(nèi)部的 touches 方法中監(jiān)聽觸摸事件措嵌,因此默認(rèn)無法讓其外界對象監(jiān)聽該 view 的觸摸事件
- 不容易區(qū)分用戶具體的手勢行為
鑒于這些問題,在iOS 3.2 之后对雪,蘋果推出了手勢識別功能(Gesture Recognizer)
- 利用 UIGestureRecognizer,能輕松識別用戶在某個 view 上面做的一些常見手勢
- UIGestureRecognizer 是一個抽象類幢哨,定義了所有手勢的基本行為臭增,使用它的子類才能處理具體的手勢
- 點(diǎn)按手勢 UITapGestureRecognizer
- 長按手勢 UILongPressGestureRecognizer
- 拖拽手勢 UIPanGestureRecognizer
- 輕掃手勢 UISwipeGestureRecognizer
- 旋轉(zhuǎn)手勢 UIRotationGestureRecognizer
- 捏合手勢 UIPinchGestureRecognizer
手勢的使用方法
- 創(chuàng)建手勢
- 添加手勢
- 實(shí)現(xiàn)手勢方法
- 補(bǔ)充(手勢也可以設(shè)置代理)
代碼示范
點(diǎn)按手勢 UITapGestureRecognizer
- (void)topGes {
UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
tapGes.delegate = self;
[self.imageView addGestureRecognizer:tapGes];
}
- (void)tap {
NSLog(@"現(xiàn)在是點(diǎn)按手勢");
}
// 代理方法:是否允許接收手指
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
//讓圖片左邊可以點(diǎn)擊紧显,右邊不能點(diǎn)擊
CGPoint curP = [touch locationInView:self.imageView];
if (curP.x > self.imageView.bounds.size.width * 0.5) {
return NO;
}else {
return YES;
}
}
長按手勢 UILongPressGestureRecognizer
- (void)longPGes {
UILongPressGestureRecognizer *longPGes = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longP:)];
[self.imageView addGestureRecognizer:longPGes];
}
//當(dāng)長按并移動時脾还,會多次調(diào)用這個方法
- (void)longP:(UILongPressGestureRecognizer *)longP {
//判斷長按時的狀態(tài)
if (longP.state == UIGestureRecognizerStateBegan) {
NSLog(@"開始長按");
}else if (longP.state == UIGestureRecognizerStateChanged) {
NSLog(@"- - - 長按時手指移動了 - - -");
}else if (longP.state == UIGestureRecognizerStateEnded) {
NSLog(@"長按結(jié)束");
}
}
拖拽手勢 UIPanGestureRecognizer
- (void)panGes {
UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self.imageView addGestureRecognizer:panGes];
}
- (void)pan:(UIPanGestureRecognizer *)pan {
//獲取偏移量
CGPoint transP = [pan translationInView:self.imageView];
NSLog(@"transP = %@", NSStringFromCGPoint(transP));
//移動圖片
self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, transP.x, transP.y);
//清零,不要累加
[pan setTranslation:CGPointZero inView:self.imageView];
}
輕掃手勢 UISwipeGestureRecognizer
- 一個手勢只能對應(yīng)一個方向肥印,若要支持多個方向识椰,可以添加多個手勢
- 輕掃手勢的方向默認(rèn)是向右
- 可以通過修改手勢的 direction 屬性修改手勢的方向
- (void)swipeGes {
//一個手勢只能對應(yīng)一個方向,若要支持多個方向深碱,可以添加多個手勢
UISwipeGestureRecognizer *swipeGes1 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
//輕掃手勢的方向默認(rèn)是向右
[self.imageView addGestureRecognizer:swipeGes1];
UISwipeGestureRecognizer *swipeGes2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
//可以修改手勢的方向腹鹉,向上
swipeGes2.direction = UISwipeGestureRecognizerDirectionUp;
[self.imageView addGestureRecognizer:swipeGes2];
UISwipeGestureRecognizer *swipeGes3 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
//手勢的方向,向左
swipeGes3.direction = UISwipeGestureRecognizerDirectionLeft;
[self.imageView addGestureRecognizer:swipeGes3];
UISwipeGestureRecognizer *swipeGes4 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
//手勢的方向敷硅,向下
swipeGes4.direction = UISwipeGestureRecognizerDirectionDown;
[self.imageView addGestureRecognizer:swipeGes4];
}
- (void)swipe:(UISwipeGestureRecognizer *)swipe {
if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) {
NSLog(@"向左輕掃 --- left");
}else if (swipe.direction == UISwipeGestureRecognizerDirectionRight){
NSLog(@"向右輕掃 --- right");
}else if (swipe.direction == UISwipeGestureRecognizerDirectionUp){
NSLog(@"向上輕掃 --- up");
} else if (swipe.direction == UISwipeGestureRecognizerDirectionDown) {
NSLog(@"向下輕掃 --- down");
}
}
旋轉(zhuǎn)手勢 UIRotationGestureRecognizer
- (void)rotationGes {
UIRotationGestureRecognizer *rotationGes = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
[self.imageView addGestureRecognizer:rotationGes];
}
- (void)rotation:(UIRotationGestureRecognizer *)rotationGes {
//獲取旋轉(zhuǎn)的度數(shù)
CGFloat angle = rotationGes.rotation;
//旋轉(zhuǎn)圖片
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, angle);
//清零
[rotationGes setRotation:0];
}
捏合手勢 UIPinchGestureRecognizer
- (void)pinchGes {
UIPinchGestureRecognizer *pinchGes = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
[self.imageView addGestureRecognizer:pinchGes];
}
- (void)pinch:(UIPinchGestureRecognizer *)pinchGes {
//獲取縮放比例
CGFloat scale = pinchGes.scale;
NSLog(@"scale = %f", scale);
//縮放圖片
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, scale, scale);
//初始化大小
[pinchGes setScale:1];
}
手勢的混合使用
- 默認(rèn)情況下只能同時支持一種手勢
- 若要同時支持多種手勢功咒,可以給要支持的手勢設(shè)置代理,并實(shí)現(xiàn)以下代理方法
// 是否允許同時支持多個手勢
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
手勢沖突的解決
- 單機(jī)和雙擊區(qū)分
[singeTap requireGestureRecognizerToFail:doubleTap];
- UIPanGestureRecognizer和UITapGestureRecognizer沖突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
return NO;
}
return YES;
}
- tableView添加手勢绞蹦,tableView父視圖添加手勢后區(qū)分
#pragma mark tapGestureRecgnizerdelegate 解決手勢沖突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UITableView class]]) {
return NO;
}
if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}
- scrollview和tableview嵌套力奋,區(qū)分滾動代理
#pragma mark - scrollView delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ([scrollView isKindOfClass:[UITableView class]]) {
NSLog(@"UITableView");
} else {
NSLog(@"UIScrollview");
}
}
- UIScrollView和子視圖TableView的cell右滑沖突
繼承UIScrollView的子類重寫下面的方法即可
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
//NSLog(@"手勢觸發(fā)的類=%@",NSStringFromClass([touch.view class]));
// 若為UITableViewCellContentView(即點(diǎn)擊了tableViewCell),則不截獲Touch事件
if ([NSStringFromClass([touch.view class])isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}return YES;
}
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
// 若為UITableViewCellContentView(即點(diǎn)擊了tableViewCell)幽七,則不截獲Touch事件
if ([NSStringFromClass([gestureRecognizer.view class])isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}
附