iOS 触摸事件五:手势处理器
2015-12-25 16:44
330 查看
通过touches方法监听触摸事件,不容易区分用户的具体手势行为。为此,苹果推出了手势处理器(UIGestureRecognizer)。手势处理器处理用户触摸事件更加简单,而且无论处理哪种触摸手势,都可以面向GestureRecognizer编程。个人认为手势处理器即为手势触摸四个方法的一种封装。
平时我们使用手势处理器一般不直接使用UIGestureRecognizer,而是使用UIGesturerecognizer提供的六大子类来处理具体的手势:
- UITapGestureRecognizer: 处理用户点击手势的手势处理器
- UIPinchGestureRecognizer: 处理用户捏合手势的手势处理器
- UIPanGestureRecognizer: 处理用户拖拽手势的手势处理器
- UISwipeGestureRecognizer: 处理用户轻扫手势的手势处理器
- UIRotationGestureRecognizer: 处理用户旋转手势的手势处理器
如果该UI控件不允许用户交互,则将该UI控件的userInteractionEnabled的属性设置为YES; 如果希望该空间可支持多点触摸,还需要将mutipleTouchEnable(是否多点触摸)设置为YES
调用该UI控件的addGestureRecognizer:方法添加该手势处理器
}
-(void)handleAction:(UIPanGestureRecognizer *)gesture{
}
}
-(void)handleAction:(UISwipeGestureRecognizer *)gesture{
}`
minmumPressDuration: 指定用户至少在屏幕上按下多少秒才会触发长按手势,默认值是0.5秒
allowableMovement:指定该长按手势允许用户移动手指的最大距离。如果用户手指按下时的移动距离超过了该距离,则长按手势失效
numberOfTouchesRequired: 指定必须使用几个手指在屏幕上长按才会触发该手势
平时我们使用手势处理器一般不直接使用UIGestureRecognizer,而是使用UIGesturerecognizer提供的六大子类来处理具体的手势:
- UITapGestureRecognizer: 处理用户点击手势的手势处理器
- UIPinchGestureRecognizer: 处理用户捏合手势的手势处理器
- UIPanGestureRecognizer: 处理用户拖拽手势的手势处理器
- UISwipeGestureRecognizer: 处理用户轻扫手势的手势处理器
- UIRotationGestureRecognizer: 处理用户旋转手势的手势处理器
手势处理器的处理用户触摸手势的步骤:
根据程序要处理的手势创建对应的手势处理器对象。创建手势处理器时需要指定target和action参数(当该控件上发生触摸手势后,该Target对象的action方法将会被激发,即目标-行为模式)如果该UI控件不允许用户交互,则将该UI控件的userInteractionEnabled的属性设置为YES; 如果希望该空间可支持多点触摸,还需要将mutipleTouchEnable(是否多点触摸)设置为YES
调用该UI控件的addGestureRecognizer:方法添加该手势处理器
UIGestureRecognizer提供的一些常用方法和属性:
UIGestureRecognizer作为所有手势处理器的基类,提供了一些常用的方法和属性: - (CGPoint)locationInView:(UIView*)view; //返回该手势在view控件中的触摸位置 - (NSUInteger)numberOfTouches; // 返回该手势包含触摸点的数量(就是用户用了几个手指进行触摸) - view: 返回激发该收拾的UI控件 - enabled: 用于设置和返回该手势处理器是否可用 - state: 只读,获取该收拾的状态,(枚举值)比如 手势刚刚开始处于UIGestureRecognizerStateBegan状态 手势改变时处于UIGestureRecognizerStateChanged状态 手势结束时处于UIGestureRecognizerStateEnded状态
UITapGestureRecognizer:
点击手势的手势处理器,继承了UIGEstureRecognizer类,除了拥有父类的属性方法外,还提供了如下的两个属性: numberOfTapsRequired: 指定该手势处理器只处理几次触摸事件,默认是1 numberOfTouchesRequired: 指定该手势处理器只能处理几个手指触摸事件,默认是1 使用: 1. 创建Tap手势
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selecor(handlePanGesture:)]; //对手势进行初始化,并指定出发该手势时的所出发(调用)的handlePanGesture:方法。 同时会传递一个UIPanGestureRecognizer类型的参数
2. 对手势的设置(可选)
tapGesture.numberOfTouchesRequired = 1;//设置手势需要的触点的数量 tapGesture.numberOfTapsRequired = 1; //设置手势需要点击的次数
3. 将手势添加到UI控件上
//调用UIView的addGestureRecognizer:方法即可 [self.view addGestureRecognizer:tapGesture]; //手势触发时调用的方法 -(void)handlePanGesture:(UIPanGestureRecognizer *)gesture{ NSLog(@"点击手势"); }
UIPinchGestureRecognizer:
捏合手势,同样继承了UIRespond类,使用步骤和点击手势处理器完全相同,额外增加了两个属性来获取相关信息: scale :获取捏合的比例 velocity : 获取捏合的速度 捏合手势一般用于图片的缩放。处理是要设置一下,避免缩放的速度过快。 使用:
//打开imgView的交互 _imgView.userInteractionEnabled = YES; //打开imgView多点触摸 ,前提,多触点事件,要打开控件的多点触摸 _imgView.multipleTouchEnabled = YES; //创建手势, target-action UIPinchGestureRecognizer *gesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)]; //为imgView添加手势 [_imgView addGestureRecognizer:gesture]; } //手势处理函数 -(void)handlePinch:(UIPinchGestureRecognizer *)gesture{ //手势处理 NSLog(@"缩放。。"); //获取捏合的比例 CGFloat scale = gesture.scale; //直接缩放 // _imgView.transform = CGAffineTransformMakeScale(scale, scale); //--第二次缩放时回到原来 //相对某个tranform进行缩放-- 在原有的基础上进行缩放 _imgView.transform = CGAffineTransformScale(_imgView.transform, scale, scale) ;//--缩放的速度太快 //优化。让缩放比例变为1,避免缩放过快 gesture.scale = 1.0f; }
UIPanGestureRecognizer:
拖拽手势, 该手势设置相关信息的属性: maximumNumberOfTouches: 设置该手势处理器最多支持几个手指拖动 minimumNumberOfTouches: 设置该手势处理器最少需要几个手指拖动 translationInView: 获取拖动手势在指定控件上的位移。该方法返回一个CGPoint类型,该结构体中的x值代表水平方向的位移,y的值代表垂直方向上的位移 velocityInView: 获取该拖动手势在指定控件上的拖动速度,该方法返回一个CGPoint类型,该结构体中的x值代表水平方向的移动速度,y的值代表垂直方向上的移动速度 ` - (void)viewDidLoad { [super viewDidLoad]; UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleAction:)]; pan.maximumNumberOfTouches = 3; //设置手势最多支持3个手指触点 pan.minimumNumberOfTouches = 1; //设置手势至少1个手指触点 [_imgView addGestureRecognizer:pan];
}
-(void)handleAction:(UIPanGestureRecognizer *)gesture{
CGPoint offSet = [gesture translationInView:_imgView]; //判断边界 _imgView.transform = CGAffineTransformTranslate(_imgView.transform, offSet.x, offSet.y); [gesture setTranslation:CGPointMake(0,0) inView:_imgView];
}
`
UISwipeGestureRecognizer:
轻扫手势,获取与轻扫相关的信息: numberOfTouchesRequired: 设置该手势只处理几个手指的触摸事件 direction: 设置该手势处理器只处理某个方向的轻扫,该属性支持上、下、左、右4个枚举值,一个手势处理器只能设置一个方向 示例 `- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. imgView = [[UIImageView alloc] initWithFrame:CGRectMake(SCREEN.size.width/2-32, SCREEN.size.height/2-32, 32,32)]; imgView.image = [UIImage imageNamed:@"a0_.9.png"]; UISwipeGestureRecognizer *swip = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleAction:)]; swip.numberOfTouchesRequired = 1; //需要一个触点 swip.direction = UISwipeGestureRecognizerDirectionUp; UISwipeGestureRecognizer *swip1 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleAction:)]; swip1.numberOfTouchesRequired = 1; //需要一个触点 swip1.direction = UISwipeGestureRecognizerDirectionRight; UISwipeGestureRecognizer *swip2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleAction:)]; swip2.numberOfTouchesRequired = 1; //需要一个触点 swip2.direction = UISwipeGestureRecognizerDirectionDown; UISwipeGestureRecognizer *swip3 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleAction:)]; swip3.numberOfTouchesRequired = 1; //需要一个触点 swip3.direction = UISwipeGestureRecognizerDirectionLeft; [self.view addSubview:imgView]; [self.view addGestureRecognizer:swip]; [self.view addGestureRecognizer:swip1]; [self.view addGestureRecognizer:swip2]; [self.view addGestureRecognizer:swip3];
}
-(void)handleAction:(UISwipeGestureRecognizer *)gesture{
CGRect rect = imgView.frame; NSLog(@"rect.x = %.2f, rect.y = %.2f", rect.origin.x, rect.origin.y); if(gesture.direction == UISwipeGestureRecognizerDirectionUp ){ //向上 NSLog(@"向上"); if(rect.origin.y >= 120){ rect.origin.y -= 20; }else{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"到头了啊" delegate:nil cancelButtonTitle:@"是" otherButtonTitles: nil]; [alert show]; } } if(gesture.direction == UISwipeGestureRecognizerDirectionRight){ //向右 NSLog(@"向右"); if(rect.origin.x+32 <= 270){ rect.origin.x += 20; }else{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"到头了啊" delegate:nil cancelButtonTitle:@"是" otherButtonTitles: nil]; [alert show]; } } if(gesture.direction == UISwipeGestureRecognizerDirectionDown){ //向下 NSLog(@"向下"); if(rect.origin.y+32 <= 500){ rect.origin.y += 20; }else{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"到头了啊" delegate:nil cancelButtonTitle:@"是" otherButtonTitles: nil]; [alert show]; } } if(gesture.direction == UISwipeGestureRecognizerDirectionLeft){ //向左 NSLog(@"向左"); if(rect.origin.x >= 20){ rect.origin.x -= 20; }else{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"到头了啊" delegate:nil cancelButtonTitle:@"是" otherButtonTitles: nil]; [alert show]; } } imgView.frame = rect;
}`
UIRotationGestureRecognizer:
旋转手势,额外定义了2个属性来获取旋转的相关信息: rotation: 获取旋转的角度 velocity: 获取旋转的速度 旋转手势同样经常用于图片的旋转处理,同样优化一下,避免旋转过快 使用与上类似:
- (void)viewDidLoad { [super viewDidLoad]; UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotation:)]; _imgView.userInteractionEnabled = YES; _imgView.multipleTouchEnabled = YES; [_imgView addGestureRecognizer:rotation]; } -(void)handleRotation:(UIRotationGestureRecognizer *)gesture{ NSLog(@"旋转"); //获取旋转的角度 CGFloat rotation = gesture.rotation; //对图片进行旋转 _imgView.transform = CGAffineTransformRotate(_imgView.transform, rotation); //优化,避免旋转过快 gesture.rotation = 0.0f; }
UILongPressGestureRecognizer:
长按手势,设置相关信息的属性:minmumPressDuration: 指定用户至少在屏幕上按下多少秒才会触发长按手势,默认值是0.5秒
allowableMovement:指定该长按手势允许用户移动手指的最大距离。如果用户手指按下时的移动距离超过了该距离,则长按手势失效
numberOfTouchesRequired: 指定必须使用几个手指在屏幕上长按才会触发该手势
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. //定义3个自定义的菜单项 transmitItem = [[UIMenuItem alloc] initWithTitle:@"转发" action:@selector(transmitClick:)]; deleteItem = [[UIMenuItem alloc] initWithTitle:@"删除" action:@selector(deleteClick:)]; reportItem = [[UIMenuItem alloc] initWithTitle:@"举报" action:@selector(reportClick:)]; //创建手势处理器,指定该控制器使用的行为方法 UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressAction:)]; _imgView.userInteractionEnabled = YES; //为视图添加手势 [_imgView addGestureRecognizer:longPressGesture]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /*自定义菜单项的点击事件*/ -(void)transmitClick:(id)sender{ NSLog(@"点击转发"); } -(void)deleteClick:(id)sender{ NSLog(@"点击删除"); } -(void)reportClick:(id)sender{ NSLog(@"点击举报"); } /*end*/ /*手势处理器的action函数, 当该方法被激活时,手势处理器会作为参数传递给该方法的参数*/ -(void)handleLongPressAction:(UILongPressGestureRecognizer *)gesture{ //"开始触摸状态"时进入 if(gesture.state == UIGestureRecognizerStateBegan){ NSLog(@"长按手势触发"); [self becomeFirstResponder]; //创建一个menu控制器 UIMenuController *menu = [UIMenuController sharedMenuController]; menu.menuItems = @[transmitItem, deleteItem, reportItem]; //悬浮在哪一个view上(定位Menu)并确定其大小 CGRect rect = CGRectMake(0, 0, 100, 50); [menu setTargetRect:rect inView:_imgView]; //展示Menu [menu setMenuVisible:YES]; } } /*end*/
相关文章推荐
- iOS学习之 plist文件的读写
- OC里面的集中数组遍历方法
- iOS开发-NSDate获取当前时区时间
- iOS中KVC和KVO有哪些用法?
- IOS 多媒体加载 加载音频 AVAudioPlayer
- iOS开发-调整文字之间间距
- iOS 去掉百度地图的 Logo(个人娱乐)
- 我的第一次份实习工作-iOS实习生-第三个月
- iOS报错:does not contain bitcode
- ios 安装Cocoapods步骤
- ioS开发中plist文件的创建与简单读取
- 我的第一次份实习工作-iOS实习生-公司使用过的软件
- ios简单动画
- iOS--隐藏状态栏
- iOS NSData、NSString、char *转换,简洁明了
- iOS图形编辑之Core Graphics
- iOS多线程NSOperation
- iOS多线程GCD
- [置顶] iOS 中 Storyboard 与 Xib 间控制器跳转 - 简化整理完整版
- iOS请求数据AFNetworking