IOS学习笔记之触摸与手势

1、触摸

     触摸就是用户的手指放在屏幕上一直到手指离开,触摸是在UIView上进行的,当用户触摸到屏幕时,触摸事件就会产生。实际上任何UI控件都是直接继承或间接继承自UIView,由此可见,所有的UI控件都可以产生触摸事件。

    当用户触摸屏幕时,事件会被封装成一个event实例,包含了触摸事件的相关信息,event实例中包含了若干个UITouch实例,一个touch表示一个手指。

2、UITouch类中常用属性

   (1)window : 触摸产生时所处的窗口

    (2)view: 触摸产生时所处的视图

    (3)tapCount: 表示短时间内轻击屏幕的次数,因此可以根据tapCount判断单击、双击或更多的轻击。

    (4)phase: 触摸事件在屏幕上有一个周期,即触摸开始、触摸点移动、触摸结束,还有中途取消。而通过phase可以查看当前触摸事件在一个周期内所处的状态。phase是UITouchPhase类型的。这是一个枚举类型,包含了:UITouchPhaseBegan(触摸开始)、UITouchPhaseMoved(接触点移动)、UITouchPhaseStationary(接触点无移动)、UITouchPhaseEnded(触摸结束)、UITouchPhaseCanceled(触摸取消)

3、响应者链

      继承了UIResponder的对象可以作为事件的响应者,当用户与某个控件交互时,该控件将会作为"第一响应者",第一响应者将作为响应者链的开始,该事件首先被发送给第一响应者,若不响应事件,将沿着响应者链一直向下传递,直到被某个响应者处理。

      通常来说,第一响应者都是UIView控件或UIView子类控件,当用户触摸该控件后,事件最先由该控件本身处理;如果该控件自身不处理事件,事件就会被传递到它的对应的视图控制器;如果该视图控制器不存在或不处理该事件,事件就会被传递到父View控件对应的视图控制器;如果事件还不被处理,事件就会传递到UIWindow;如果UIWindow对象也不处理,事件则会传递到UIApplication的委托对象;如果UIApplication也不处理该事件,那么该事件就会被丢弃。

4、响应触摸的方法

  (1)-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;当用户开始触摸时激发该方法

    在该方法中,用event 的allTouches方法获取当前的触摸对象的所有集合

    NSSet *allTouches = [event allTouches];   

    NSLog(@"手指数量:%li",allTouches.count);

    //获取任意一个触摸对象

    UITouch *touch = [allTouches anyObject];

    NSLog(@"段时间内点击的次数:%li",touch.tapCount);

   //返回触摸点的坐标

   CGPoint point = [touch locationInView:touch.view];

    NSLog(@"x is %.2f, y is %.2f",point.x,point.y);

  (2)-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;当触摸移动时激发该方法

  (3)-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;当触摸结束时激发该方法

  (4)-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;当系统事件(比如内存不足、电话呼入)终止了触摸事件时激发该方法。

5、手势

    手势处理器(UIGestureRecognizer)使得处理用户触摸事件更加简单,而且无论处理哪种触摸手势,都可面向Gesture Recognizer编程。

    UIGestureRecognizer提供了如下子类来处理具体的手势

    UITapGestureRecognizer:处理用户点击手势的手势处理器

    UIPinchGestureRecognizer:处理用户捏合手势的手势处理器

    UIPanGestureRecognizer:处理用户拖拽手势的手势处理器

    UISwipeGestureRecognizer:处理用户轻扫的手势处理器

    UIRotationGestureRecognizer:处理用户旋转手势的手势处理器

    UILongPressGestureRecognizer:处理用户长按手势的手势处理器

  (1)使用手势处理器处理用户触摸手势的步骤如下:

      根据程序需要处理的手势创建对应的手势处理器对象。创建手势处理器时需要指定target和action参数;

      如果该UI控件不允许用户交互,则将该UI控件的userInteractionEnabled属性设置为YES;如果希望该控件可支持多点触摸,还需要将mutipleTouchEnabled设置为YES

     调用该UI控件的addGestureRecognizer:方法添加该手势处理器。

  (2)UIGestureRecognizer作为所有手势处理器的基类,它提供了如下的常用方法和属性:

     -(CGPoint)locationInView:(UIView *)view;返回该手势在view控件中的触摸位置

    -(NSUInteger)numberOfTouches;返回该手势包含触摸点的数量;

    view:返回激发该手势的UI控件

    enabled:用于设置和返回该手势处理器是否可用

    state:获取该手势的状态,比如手势开始(UIGestureRecognizerStateBegan),手势改变时(UIGestureRecognizerStateChanged),手势结束时(UIGestureRecognizerStateEnded) 

6、点击手势(UITapGestureRecognizer)

   该类提供了两个属性:numberOfTapsRequired:指定该手势处理器只处理几次触摸事件

   numberOfTouchesRequired:指定该手势处理器只处理几个手指的触摸事件

   @property (nonatomic, weak) IBOutlet UILabel *lbGesture;

   //实例化一个手势对象

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick:)];

    tapGesture.numberOfTapsRequired = 1;//点击的次数

    //设置手指的数量

    tapGesture.numberOfTouchesRequired =1;

    [_lbGesture addGestureRecognizer:tapGesture];

 

-(void)tapClick:(UITapGestureRecognizer *)tapGesture{

    NSLog(@"轻拍");

    //CGPoint point = [tapGesture locationInView:tapGesture.view];//相对于label的坐标

    CGPoint point = [tapGesture locationInView:self.view];//相对于self.view的坐标

    NSLog(@"x is %.2f,y is %.2f",point.x,point.y);

    switch (tapGesture.state) {

        case UIGestureRecognizerStateBegan:

            NSLog(@"触摸开始");

            break;

         case UIGestureRecognizerStateChanged:

            NSLog(@"改变");

            break;

        case UIGestureRecognizerStateEnded:

            NSLog(@"结束");

            break;

        default:

            

            break;

    }

}

7、捏合手势(UIPinchGestureRecognizer)

   它有两个属性获取捏合的相关信息:scale:获取捏合的比例

   velocity:获取捏合的速度 

   UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGesture:)]; 

    [_imageView addGestureRecognizer:pinchGesture];

-(void)pinchGesture:(UIPinchGestureRecognizer *)gesture{

    CGFloat scale = gesture.scale;//捏合比例

    //NSLog(@"%.2f",scale);

    //捏合速度

    //CGFloat velocity = gesture.velocity;

    //_imageView.transform = CGAffineTransformMakeScale(scale, scale);

    //在原有的基础上进行缩放

    _imageView.transform = CGAffineTransformScale(_imageView.transform, scale, scale);

    gesture.scale = 1.0;

}

8、旋转手势(UIRotationGestureRecognizer)

   它有两个属性来获取旋转的相关信息:rotation:获取旋转的角度

   velocity:获取旋转的速度

     UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGesture:)];

    [_imgView addGestureRecognizer:rotationGesture];

-(void)rotationGesture:(UIRotationGestureRecognizer *)gesture{

    CGFloat rotation = gesture.rotation;

    _imgView.transform = CGAffineTransformRotate(_imgView.transform, rotation);

    gesture.rotation = 0.0f;

}

9、轻扫手势(UISwipeGestureRecognizer)

   它设置了两个属性来获取轻扫的相关信息:numberOfTouchesRequired:设置该手势处理器只处理几个手指的触摸事件;direction:设置该手势处理器只处理某个方向的轻扫

   在应用中可以只创建某个方向的手势,也可以同时将四个方向的手势加到同一控件中。

   (1)为控件添加一个方向的轻扫手势处理器

// 创建手势处理器,指定使用该控制器的handleSwipe方法处理手势

UISwipeGestureRecognizer *swipeGestureLeft=[[UISwipeGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSwipe:)];

// 设置该手势处理器只处理1个手指的轻扫手势 

swipeGestureLeft.numberOfTouchesRequired=1;

// 设置该手势处理器的轻扫方向

swipeGestureLeft.direction=UISwipeGestureRecognizerDirectionLeft;

// 为self.view添加手势处理器

[self.view addGestureRecognizer:swipeGestureLeft];

  (2)为控件添加4个方向的轻扫手势处理器

    for (int i = 0; i < 4; i++) {

        UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];

        [swipeGesture setDirection:1 << i];//设置滑动手势为左滑动

        [self.view addGestureRecognizer:swipeGesture];

    }

   

-(void)swipe:(UISwipeGestureRecognizer *)swipeRecognizer{

    //NSLog(@"滑动");

    switch (swipeRecognizer.direction) {

        case UISwipeGestureRecognizerDirectionLeft:

            NSLog(@"向左");

            break;

        case UISwipeGestureRecognizerDirectionRight:

            NSLog(@"向右");

            break;            

        case UISwipeGestureRecognizerDirectionUp:

            NSLog(@"向上");

            break;            

        case UISwipeGestureRecognizerDirectionDown:

            NSLog(@"向下");

            break;

        default:

            break;

    }

}

10、拖动手势(UIPanGestureRecognizer)

    maximumNumaberOfTouches:设置该手势处理器最多支持几个手指的拖动

    minimumNumberOfTouches:设置该手势处理器最少需要几个手指拖动

    tranlationInView:获取该拖动手势在指定控件上的位移。该方法返回一个CGPoint类型,该结构体中的x的值代表水平方向的位移,y代表垂直方向的位移

   velocityInView:获取该拖动手势在指定控件上的拖动速度。该方法返回一个CGPoint类型,该结构体中的x的值代表水平方向的移动速度,y的值代表垂直方向的移动速度

   

   UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)];

   panGesture.minimumNumaberOfTouches = 1;

   panGesture.maximumNumaberOfTouches = 2;

    [_imageView addGestureRecognizer:panGesture];

-(void)panHandler:(UIPanGestureRecognizer *)panGesture{

    CGPoint point = [panGesture translationInView:panGesture.view];

    _imageView.transform = CGAffineTransformTranslate(_imageView.transform, point.x, point.y);

    [panGesture setTranslation:CGPointMake(0, 0) inView:_imageView];

}

11、长按手势(UILongPressGestureRecognizer)

     minimumPressDuration:指定用户至少在屏幕上按下多少秒才会触发该长按手势,默认值是0.5

     allowableMovement指定用户移动手指的最大距离

     numberOfTouchesRequired:指定必须使用几个手指在屏幕上长按才会发出该手势

UILongPressGestureRecognizer *pressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pressGesture:)];

    pressGesture.minimumPressDuration = 1; //设置至少在屏幕上按下多少秒才能长按手势

    pressGesture.allowableMovement = 1; //设置长按手势允许用户移动手指的最大距离

    pressGesture.numberOfTouchesRequired = 1; //设置必须使用几个手指长按才会发出该手势

    [_lbTitle addGestureRecognizer:pressGesture];

-(void)pressGesture:(UILongPressGestureRecognizer *)gesture{

    if (gesture.state == UIGestureRecognizerStateBegan) {

        [self becomeFirstResponder];

        UIMenuController *menuController = [UIMenuController sharedMenuController];

        UIMenuItem *_shareItem= [[UIMenuItem alloc] initWithTitle:@"分享" action:@selector(shareClick)];

        UIMenuItem *_copyItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyClick)];

        UIMenuItem *_translaterItem = [[UIMenuItem alloc] initWithTitle:@"转发" action:@selector(translaterClick)];

        menuController.menuItems = @[_shareItem,_copyItem,_translaterItem];

        [menuController setTargetRect:_lbTitle.bounds inView:_lbTitle];

        [menuController update];

        [menuController setMenuVisible:YES animated:YES];

    }

}

-(void)shareClick{

    NSLog(@"分享");

}

-(void)copyClick{

     NSLog(@"复制");

}

-(void)translaterClick{

     NSLog(@"转发");

}

#pragma mark UIMenuController

//使menu所处的View成为第一响应者

-(BOOL)canBecomeFirstResponder{  

    return YES;

}

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender{   

    if (action == @selector(shareClick)) {

        return YES;

    }else if (action == @selector(copyClick)){

        return YES;

    }else if (action == @selector(translaterClick)){

        return YES;

    }

    return [super canPerformAction:action withSender:sender];

}

12、若想要两个不同的手势加在同一个控件上,则可以用以下方法来执行

  //继承一个手势控件 

@interface MyRotation : UIRotationGestureRecognizer

@end

@implementation MyRotation

/*

 是否阻止另一个手势

 */

-(BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer{

    return NO;

}

-(BOOL)canBePreventedGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer{

    return NO;

}

    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGesture:)];   

    [_imgView addGestureRecognizer:pinchGesture]; 

    MyRotation *rotationGesture = [[MyRotation alloc] initWithTarget:self action:@selector(rotationGesture:)];  

    [_imgView addGestureRecognizer:rotationGesture];

-(void)rotationGesture:(UIRotationGestureRecognizer *)gesture{

    CGFloat rotation = gesture.rotation;

    _imgView.transform = CGAffineTransformRotate(_imgView.transform, rotation);

    gesture.rotation = 0.0f;

}

-(void)pinchGesture:(UIPinchGestureRecognizer *)gesture{

    CGFloat scale = gesture.scale;

    _imgView.transform = CGAffineTransformScale(_imgView.transform, scale, scale);

    gesture.scale = 1.0f;

}

这样图片就可以一边旋转一边移动了。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值