iOS 触摸事件五:手势处理器

来源:互联网 发布:淘宝评价怎么不能晒图 编辑:程序博客网 时间:2024/06/14 02:44

通过touches方法监听触摸事件,不容易区分用户的具体手势行为。为此,苹果推出了手势处理器(UIGestureRecognizer)。手势处理器处理用户触摸事件更加简单,而且无论处理哪种触摸手势,都可以面向GestureRecognizer编程。个人认为手势处理器即为手势触摸四个方法的一种封装。
平时我们使用手势处理器一般不直接使用UIGestureRecognizer,而是使用UIGesturerecognizer提供的六大子类来处理具体的手势:
- UITapGestureRecognizer: 处理用户点击手势的手势处理器
- UIPinchGestureRecognizer: 处理用户捏合手势的手势处理器
- UIPanGestureRecognizer: 处理用户拖拽手势的手势处理器
- UISwipeGestureRecognizer: 处理用户轻扫手势的手势处理器
- UIRotationGestureRecognizer: 处理用户旋转手势的手势处理器

手势处理器的处理用户触摸手势的步骤:

  1. 根据程序要处理的手势创建对应的手势处理器对象。创建手势处理器时需要指定target和action参数(当该控件上发生触摸手势后,该Target对象的action方法将会被激发,即目标-行为模式)
  2. 如果该UI控件不允许用户交互,则将该UI控件的userInteractionEnabled的属性设置为YES; 如果希望该空间可支持多点触摸,还需要将mutipleTouchEnable(是否多点触摸)设置为YES
  3. 调用该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*/
0 0
原创粉丝点击