开启userInteractionEnabled

// 创建图片视图
- (void) creareImg {
    UIImage* image = [UIImage imageNamed:@"zz.jpeg"];
    _imageView = [[UIImageView alloc] initWithImage:image];
    UIScreen* screen = [UIScreen mainScreen];
    const int width = 200;
    const int height = 100;
    const float x = screen.bounds.size.width / 2 - width / 2;
    const float y = screen.bounds.size.height / 2 - height;
    _imageView.frame = CGRectMake(x, y, width, height);
    _imageView.userInteractionEnabled = YES;
    [self.view addSubview:_imageView];
}

了解UIGestrueRecognizer

属性
stateUIGestureRecognizerState当前手势状态,可分为手势开始,手势改变,手势结束等等
enabledBOOL是否启用YES
viewUIView手势监听的视图
requiresExclusiveTouchTypeBOOL是否忽略其他手势类型,设置为YES将只响应一种手势类型NO
numberOfTouchesNSUInteger多少根手指触发手势1
API
  • - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action 初始化并添加事件监听函数
  • - (void)addTarget:(id)target action:(SEL)action 添加事件监听函数
  • - (void)removeTarget:(nullable id)target action:(nullable SEL)action 删除事件监听函数
  • - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer 添加其他手势冲突失效器,当触发当前手势时,指定的手势将失效。
  • - (CGPoint)locationInView:(nullable UIView*)view 获取相对于指定视图的坐标位置
  • - (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view 获取指定手指相对指定视图的坐标位置
代理协议
  • - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 手势准备开启时候触发,返回NO则取消手势。
  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 当手势与其他手势同时发生识别时候触发,返回YES运行两个手势同时进行,返回NO则阻止同时识别。
  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 是否给事件接收手指。在手势开始触发事件触发前触发,返回NO可以阻止事件获取触摸的手指。
  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press 是否给按下事件接收手指,在按下手势事件触发前触发。返回NO可阻止事件获取触摸的手指。
我们了解清除GestureRecognizer 类,下面我们来了解其子类手势的使用。

UITapGestureRecognizer 点击手势

// 创建点击手势
- (void) createTapGes {
    _imageView.userInteractionEnabled = YES; // 开启响应事件属性
    UITapGestureRecognizer* tapOneGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(big)]; // 创建手势
    tapOneGes.numberOfTapsRequired = 1; // 触发事件的点击次数
    tapOneGes.numberOfTouchesRequired = 1; // 触发事件的手指数量
    [_imageView addGestureRecognizer:tapOneGes]; // 添加手势监听器
}
// 点击触发事件
- (void) big {
    UIScreen* screen = [UIScreen mainScreen];
    [UIView beginAnimations:nil context:nil]; // 开始布局动画
    _imageView.frame = CGRectMake(0, 0, screen.bounds.size.width, screen.bounds.size.height);
    [UIView commitAnimations]; // 结束布局动画
}

UIPinchGestureRecognizer 捏合手势

// 捏合手势
- (void) createPinchGes {
    UIPinchGestureRecognizer* pinch = [[UIPinchGestureRecognizer alloc] init]; // 创建手势
    [pinch addTarget:self action:@selector(scale:)]; // 添加事件函数
    pinch.delegate = self; // 设置代理
    [_imageView addGestureRecognizer:pinch]; // 视图添加手势监听器
}

- (void) scale: (UIPinchGestureRecognizer*) pinch {
    UIView* IView = pinch.view; // 获取监听的视图
    CGAffineTransform transiform = CGAffineTransformScale(IView.transform, pinch.scale, pinch.scale); // 计算缩放后的矩阵
    if (transiform.a < 0.4) { // 缩放小于0.4阻止
        transiform.a = 0.4;
        transiform.d = 0.4;
    }
    IView.transform = transiform; // 重新设置矩阵
    pinch.scale = 1; // 重置缩放矩阵,否则手势会一直累加
}

// 添加允许多个手势触发代理函数
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return  YES;
}

上面代码中我们通过获取捏合手势的scale 属性获取用户捏合缩放的大小。并且使用内置api CGAffineTransformScale 重新计算了视图的2D矩阵(矩阵表示图像变形,可以了解一下图形学),注意!最后一步中必须重置手势的scale 否则会一直累加导致计算矩阵错误,如果不想重置的话那就需要修改 CGAffineTransformScale 的第一个参数为基础矩阵参数。

UIRotationGestureRecognizer 旋转手势

// 旋转手势
- (void) createRotateGes {
    UIRotationGestureRecognizer* rotate = [[UIRotationGestureRecognizer alloc] init];
    [rotate addTarget:self action:@selector(rotate:)];
    rotate.delegate = self;
    [_imageView addGestureRecognizer:rotate];
}
// 旋转触发事件
- (void) rotate: (UIRotationGestureRecognizer*) rotate {
    UIView* IView = rotate.view;
    IView.transform =  CGAffineTransformRotate(IView.transform, rotate.rotation); // 重新计算视图矩阵
    rotate.rotation = 0;
}

UIPanGestureRecognizer 平移手势

// 平移手势
- (void) createPanGes {
    UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    pan.delegate = self;
    [_imageView addGestureRecognizer:pan];
}
- (void) pan: (UIPanGestureRecognizer*)pan {
    CGPoint speed = [pan velocityInView:_imageView]; // 获取移动速度
    NSLog(@"x速度= %f, y速度= %f", speed.x, speed.y);
    CGPoint translation = [pan translationInView:_imageView]; // 获取移动矩阵
    CGAffineTransform transform = CGAffineTransformTranslate(_imageView.transform, translation.x, translation.y);
    _imageView.transform = transform;
}

UILongPressGestureRecognizer 长按手势

// 长按手势
- (void) createLongPassGes {
    UILongPressGestureRecognizer* longPass = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pass:)];
    longPass.minimumPressDuration = 1; // 设置长按触发时间,默认0.5
    [_imageView addGestureRecognizer: longPass];
}

- (void)pass: (UILongPressGestureRecognizer*) longPass {
    if (longPass.state == UIGestureRecognizerStateBegan) {
        NSLog(@"开始长按");
    } else if (longPass.state == UIGestureRecognizerStateEnded) {
        NSLog(@"结束长按");
    } else if (longPass.state == UIGestureRecognizerStateChanged) {
        NSLog(@"长按发生改变");
    }
}

UISwipeGestureRecognizer 轻滑手势

// 创建轻滑手势
- (void) createSwipe {
    UISwipeGestureRecognizer* swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swiper:)];
    swipe.direction = UISwipeGestureRecognizerDirectionDown;
    [_imageView addGestureRecognizer: swipe];
    swipe.delegate = self;
}

- (void) swiper: (UISwipeGestureRecognizer*)swiper {
    NSLog(@"发生向下滑动");
}
03-05 21:00