iOS开发之UI篇(5)—— 添加手势
2017-11-23 21:42
274 查看
版本
Xcode 9.11. 六种常用手势:
UITapGestureRecognizer:点击手势UIPinchGestureRecognizer:捏合手势(放大缩小)
UIRotationGestureRecognizer:旋转手势
UISwipeGestureRecognizer:滑动手势
UIPanGestureRecognizer:拖动手势
UILongPressGestureRecognizer:长按手势
2. 解决手势冲突
手势识别实际上是调用触摸事件来实现的。如果一个手势A的识别部分是另一个手势B的子部分时,默认情况下A就会先识别,B就无法识别了,造成手势冲突。例如拖动手势(UIPanGestureRecognizer)的操作事件是在手势的开始状态(UIGestureRecognizerStateBegan)开始执行的,而滑动手势(UISwipeGestureRecognizer)的操作事件只有在手势结束状态(UIGestureRecognizerStateEnded)才能执行,因此能识别拖动手势而不能识别滑动手势。解决手势冲突办法:
使用requireGestureRecognizerToFail:方法,指定某个手势执行的前提是另一个手势失败后才会执行。
例如:
/* 解决手势冲突 */ // 解决 单击 与 双击 之间的冲突 [singleTap requireGestureRecognizerToFail:doubleTap]; // 解决 拖动 与 滑动 之间的冲突 [pan requireGestureRecognizerToFail:swipeToLeft]; [pan requireGestureRecognizerToFail:swipeToRight]; // 解决 拖动 和 长按 之间的冲突 [longPress requireGestureRecognizerToFail:pan];
3. 手势在视图控件之间的传递(响应链)
和触摸事件一样,默认情况下,子视图(上层视图)触摸事件执行后就不再向父视图(下层视图)传递。如果想继续往下传递手势,可利用代理方法gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer:来实现。此代理方法默认返回NO,会阻断继续向下识别手势,如果返回YES则可以继续向下传递手势。示例
注意UIImageView默认userInteractionEnabled为NO,这就无法识别手势。本例使用storyboard创建UIImageView并设置userInteractionEnabled为YES。
GestureVC.m
#import "GestureVC.h" @interface GestureVC () <UIGestureRecognizerDelegate> { NSInteger _currentIndex; } @property (weak, nonatomic) IBOutlet UILabel *label; @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end @implementation GestureVC - (void)viewDidLoad { [super viewDidLoad]; /* ----- 点击手势 ----- */ // 默认单击 UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGesture:)]; [self.imageView addGestureRecognizer:singleTap]; // 双击 UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapGesture:)]; doubleTap.numberOfTapsRequired = 2; // 需要2根手指一起敲击 // tap.numberOfTouchesRequired = 2; // 把点击手势添加到imageView上 [self.imageView addGestureRecognizer:doubleTap]; /* ----- 捏合手势 ----- */ // 模拟器触发:按住option键,再点鼠标左键 UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGesture:)]; [self.imageView addGestureRecognizer:pinch]; /* ----- 旋转手势 ----- */ // 模拟器触发:也是按住option键 UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGesture:)]; [self.imageView addGestureRecognizer:rotation]; /* ----- 滑动手势 ----- */ // 默认往右滑 UISwipeGestureRecognizer *swipeToRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeToRightGesture:)]; [self.imageView addGestureRecognizer:swipeToRight]; // 改成往左滑 UISwipeGestureRecognizer *swipeToLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeToLeftGesture:)]; swipeToLeft.direction = UISwipeGestureRecognizerDirectionLeft; [self.imageView addGestureRecognizer:swipeToLeft]; // 支持两个方向(左+右/上+下),不同时支持横向和竖向,优先支持横向 // swipe.direction = UISwipeGestureRecognizerDirectionLeft|UISwipeGestureRecognizerDirectionRight; /* ----- 拖动手势 ----- */ UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; [self.imageView addGestureRecognizer:pan]; /* ----- 长按手势 ----- */ UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGesture:)]; // 设置长按时间 longPress.minimumPressDuration = 1.0f; [self.imageView addGestureRecognizer:longPress]; /* 解决手势冲突 */ // 解决 单击 与 双击 之间的冲突 [singleTap requireGestureRecognizerToFail:doubleTap]; // 解决 拖动 与 滑动 之间的冲突 [pan requireGestureRecognizerToFail:swipeToLeft]; [pan requireGestureRecognizerToFail:swipeToRight]; // 解决 拖动 和 长按 之间的冲突 [longPress requireGestureRecognizerToFail:pan]; } #pragma mark - 手势识别响应方法 // 单击手势 - (void)singleTapGesture:(UITapGestureRecognizer *)gesture { NSLog(@"singleTapGesture"); self.label.hidden = !self.label.hidden; } // 双击手势 - (void)doubleTapGesture:(UITapGestureRecognizer *)gesture { NSLog(@"doubleTapGesture"); // 取消一切形变 self.imageView.transform = CGAffineTransformIdentity; } // 捏合手势 - (void)pinchGesture:(UIPinchGestureRecognizer *)gesture { NSLog(@"pinchGesture"); if (gesture.state == UIGestureRecognizerStateChanged) { // 手势进行中 // 捏合手势中scale属性记录了缩放比例 self.imageView.transform = CGAffineTransformMakeScale(gesture.scale, gesture.scale); }else if(gesture.state == UIGestureRecognizerStateEnded) { // 手势结束 } } // 旋转手势 - (void)rotationGesture:(UIRotationGestureRecognizer *)gesture { NSLog(@"rotationGesture"); if (gesture.state == UIGestureRecognizerStateChanged) { // 手势进行中 // 旋转手势中rotation属性记录了旋转弧度 self.imageView.transform = CGAffineTransformMakeRotation(gesture.rotation); }else if(gesture.state == UIGestureRecognizerStateEnded) { // 手势结束 } } // 向左滑动手势 - (void)swipeToLeftGesture:(UISwipeGestureRecognizer *)gesture { NSLog(@"swipeToLeftGesture"); // 上一张图片 _currentIndex--; if (_currentIndex < 0) { _currentIndex = 2; }else if (_currentIndex >2) { _currentIndex = 0; } self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld.jpg",_currentIndex]]; } // 向右滑动手势 - (void)swipeToRightGesture:(UISwipeGestureRecognizer *)gesture { NSLog(@"swipeToRightGesture"); // 下一张图片 _currentIndex++; if (_currentIndex < 0) { _currentIndex = 2; }else if (_currentIndex >2) { _currentIndex = 0; } self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld.jpg",_currentIndex]]; } // 拖动手势 - (void)panGesture:(UIPanGestureRecognizer *)gesture { NSLog(@"panGesture"); if (gesture.state == UIGestureRecognizerStateChanged) { // 手势进行中 // 取得在相对根视图(self.view)的移动 CGPoint translation = [gesture translationInView:self.view]; // 改变imageView坐标 self.imageView.transform = CGAffineTransformMakeTranslation(translation.x, translation.y); }else if(gesture.state == UIGestureRecognizerStateEnded){ // 0.5s后取消一切形变 [UIView animateWithDuration:0.5 animations:^{ self.imageView.transform = CGAffineTransformIdentity; }]; } } // 长按手势 - (void)longPressGesture:(UILongPressGestureRecognizer *)gesture { NSLog(@"longPressGesture"); // 此方法会调用两次(Began & Ended),需判断其手势状态 if (gesture.state == UIGestureRecognizerStateBegan) { // 创建alertController UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"确定删除这张图片吗?" preferredStyle:UIAlertControllerStyleActionSheet]; // 添加确认按钮 [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){ // 这里啥也不做 }]]; // 添加取消按钮 [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { // 这里啥也不做 }]]; // 显示alertController [self presentViewController:alertController animated:YES completion:nil]; } } @end
![](http://upload-images.jianshu.io/upload_images/8900795-eaba8da44ee1e133.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
效果图
相关文章推荐
- ios开发中的手势添加
- iOS开发,UISlider滑块不灵敏问题以及在UIScrollView上添加Slider造成手势冲突问题心得
- ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明
- IOS开发UI篇之──键盘添加工具条
- IOS开发UI篇之──键盘添加工具条
- IOS开发UI篇之──键盘添加工具条
- IOS应用开发09——为自定义UITableViewCell的部分区域添加手势
- ios开发之手势动作状态细分state,同一视图添加两个手势
- iOS开发中的手势添加
- iOS软件开发之在UIScrollView上添加手势不能触发解决办法
- IOS开发UI篇之──键盘添加工具条
- IOS开发:添加了手势UITapGestureRecognizer,但是点击却没任何反应
- IOS开发UI篇之──键盘添加工具条
- 李洪强iOS开发之添加手势
- IOS开发UI篇之──键盘添加工具条
- iOS开发UI篇—实现一个简单的手势解锁应用(基本)
- ios开发-给cell添加长按手势
- iOS开发UI篇—实现一个简单的手势解锁应用(基本) - 文顶顶
- ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明
- iOS开发UI篇—实现一个简单的手势解锁应用(基本)