码迷,mamicode.com
首页 > 其他好文 > 详细

手势识别

时间:2015-04-13 00:11:58      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:

iOS3.2版本之后,苹果推出了手势识别,其目的是:
  • 简化开发者的开发难度
  • 统一用户体验
 
iOS目前支持的手势识别
  • UITapGestureRecognizer(点按)
  • UIPinchGestureRecognizer(捏合)
  • UIPanGestureRecognizer(拖动)
  • UISwipeGestureRecognizer(轻扫)
  • UIRotationGestureRecognizer(旋转)
  • UILongPressGestureRecognizer(长按)
 
手势识别的状态
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
    // 没有触摸事件发生,所有手势识别的默认状态
     UIGestureRecognizerStatePossible,
    // 一个手势已经开始但尚未改变或者完成时
     UIGestureRecognizerStateBegan,
    // 手势状态改变
    UIGestureRecognizerStateChanged,
    // 手势完成
    UIGestureRecognizerStateEnded,
    // 手势取消,恢复至Possible状态
    UIGestureRecognizerStateCancelled,
    // 手势失败,恢复至Possible状态
    UIGestureRecognizerStateFailed,
    // 识别到手势识别
    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
 
};
 
手势识别状态变化示意图
 
技术分享
 

UIGestureRecognizer
 
初始化GestureRecognizer
- (instancetype)initWithTarget:(id)target  action:(SEL)action
 
添加和删除Targets和Action 
- (void)addTarget:(id)target  action:(SEL)action
- (void)removeTarget:(id)target  action:(SEL)action
 
获取touches 和 location
- (CGPoint)locationInView:(UIView *)view
参数:view,手势发生的View,赋值为nil 则默认指window
 
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex
                    inView:(UIView *)view
获取手势touches其中一个touch的位置
 
- (NSUInteger)numberOfTouches
返回touch的个数
 
得到Recognizer的state和View
@property(nonatomic, readonly) UIGestureRecognizerState state
@property(nonatomic, readonly) UIView *view
@property(nonatomic, getter=isEnabled) BOOL enabled     //当前手势是否可用
 

UIGestureRecognizer 子类
UITapGestureRecognizer (点按)
@property(nonatomic) NSUInteger numberOfTapsRequired
点按手势被识别时点按的次数(默认是1)
 
@property(nonatomic) NSUInteger numberOfTouchesRequired
点按手势被识别时手指的个数(默认是1)
 
注意:调用 locationInView:时,(1)如果是多次点击,location是第一次点击是的位置;
(2)如果是多点点击,location是这几点的中心位置;如果想获得某一点的位置,可调用locationOfTouch:inView:
 
代码示例:
#pragma mark - 点按手势
- (void)tap:(UITapGestureRecognizer *)recognizer
{
    // 双击放大图片
    UIImageView *imageView = (UIImageView *)recognizer.view;

    [UIView animateWithDuration:0.8f animations:^{
        [imageView setTransform:CGAffineTransformScale(imageView.transform, 2.0, 2.0)];
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5f animations:^{
            [imageView setTransform:CGAffineTransformScale(imageView.transform, 0.5, 0.5)];
        }];
    }];
}

 

====================================================================================
UIPinchGestureRecognizer (捏合)
@property(nonatomic) CGFloat scale
@property(nonatomic, readonly) CGFloat velocity
注意: 在设置累加形变参数时,需要充值手势的缩放比例 recognizer.scale = 1.0f;
 
代码示例:
#pragma mark - 捏合
- (void)pinch:(UIPinchGestureRecognizer *)recognizer
{
    // 调整图像的显示比例
    if (UIGestureRecognizerStateChanged == recognizer.state) {
        
        // 等比例缩放
        [recognizer.view setTransform:CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale)];
        
        // 在设置累加形变参数时,需要重置手势的缩放比例
        recognizer.scale = 1.0f;
    }
}

 

====================================================================================
UISwipeGestureRecognizer (轻扫)
@property(nonatomic) UISwipeGestureRecognizerDirection direction
清扫方向,默认方向是向右
typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) {
    UISwipeGestureRecognizerDirectionRight = 1 << 0,
    UISwipeGestureRecognizerDirectionLeft  = 1 << 1,
    UISwipeGestureRecognizerDirectionUp    = 1 << 2,
    UISwipeGestureRecognizerDirectionDown  = 1 << 3
}; 
@property(nonatomic) NSUInteger numberOfTouchesRequired
手指轻扫的个数,默认为1
 
代码示例:
#pragma mark - 轻扫
- (void)swipe:(UISwipeGestureRecognizer *)recognizer
{
    NSLog(@"%d", recognizer.direction);
    if (UISwipeGestureRecognizerDirectionDown == recognizer.direction) {
        NSLog(@"向下");
    } else if (UISwipeGestureRecognizerDirectionUp == recognizer.direction) {
        NSLog(@"向上");
    } else if (UISwipeGestureRecognizerDirectionLeft == recognizer.direction) {
        NSLog(@"向左");
    } else if (UISwipeGestureRecognizerDirectionRight == recognizer.direction) {
        NSLog(@"向右");
    }
}

 

====================================================================================
UIPanGestureRecognizer (拖动)
@property(nonatomic) NSUInteger maximumNumberOfTouches
@property(nonatomic) NSUInteger minimumNumberOfTouches
 
- (CGPoint)translationInView:(UIView *)view
拖动手势在指定view上的位移
 
- (void)setTranslation:(CGPoint)translation inView:(UIView *)view
设置拖动手势在特定view上的位移
- (CGPoint)velocityInView:(UIView *)view
 
代码示例:
#pragma mark - 拖动
- (void)pan:(UIPanGestureRecognizer *)recognizer
{
    CGPoint translation = [recognizer translationInView:self.view];
    
    // 让图像根据手指移动
    if (UIGestureRecognizerStateChanged == recognizer.state) {
        // 形变参数,有Make的时候,是相对初始位置计算的
        // 没有Make是递增修改形变的
        [recognizer.view setTransform:CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y)];
        
        // 拖动手指中的平移距离是相对于初始位置,如果使用CGAffineTransformTranslate累加形变方法
        // 需要在每次位移之后,重置recognizer的位移量,就是将位移量清零
        [recognizer setTranslation:CGPointZero inView:recognizer.view];
    }
}
====================================================================================
UIRotationGestureRecognizer (旋转)
@property(nonatomic) CGFloat rotation
@property(nonatomic, readonly) CGFloat velocity
 
代码示例:
#pragma mark - 旋转
- (void)rotate:(UIRotationGestureRecognizer *)recognizer
{
    if (UIGestureRecognizerStateChanged == recognizer.state) {
        recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
        
        // 重置旋转量
        recognizer.rotation = 0.0f;
    }
}
====================================================================================
UILongPressGestureRecognizer (长按)
@property(nonatomic) CFTimeInterval minimumPressDuration 默认为0.5秒
@property(nonatomic) NSUInteger numberOfTouchesRequired
@property(nonatomic) NSUInteger numberOfTapsRequired 默认为0
@property(nonatomic) CGFloat allowableMovement
长按手势识别所允许的最大移动距离,默认为10point,超过则识别失败
 
代码示例:
#pragma mark - 长按手势
- (void)longPress:(UILongPressGestureRecognizer *)recognizer
{
    NSLog(@"长按");
    // 长按旋转图片
    // 开始长按
    // 在形变时,iOS采取就近原则旋转,如果不能按照希望的方向旋转,可以增加一些修正值,例如0.01
    // 直接通过形变属性,要实现一次性转一圈,比较困难,可以分两次进行
    if (UIGestureRecognizerStateBegan == recognizer.state) {
        [UIView animateWithDuration:0.8f animations:^{
            [recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, M_PI - 0.01)];
        }];
    } else if (UIGestureRecognizerStateEnded == recognizer.state) {
        [UIView animateWithDuration:0.8f animations:^{
            [recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, M_PI - 0.01)];
        } completion:^(BOOL finished) {
            // 清除所有的形变属性
            [recognizer.view setTransform:CGAffineTransformIdentity];
        }];
    }
}
====================================================================================
UIScreenEdgePanGestureRecognizer (屏幕边缘拖动)- iOS7
@property(readwrite, nonatomic, assign) UIRectEdge edges
 
 

手势识别

标签:

原文地址:http://www.cnblogs.com/kangshang/p/4420913.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!