您的位置:首页 > 产品设计 > UI/UE

iOS开发之UI篇(5)—— 添加手势

2017-11-23 21:42 274 查看

版本

Xcode 9.1

1. 六种常用手势:

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




效果图
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息