美文网首页
iOS UIView添加手势回调

iOS UIView添加手势回调

作者: 弹吉他的少年 | 来源:发表于2020-09-28 10:29 被阅读0次

    前言

    · UIView是我们在开发中经常使用到的控件,很多时候需要在该控件上面添加手势处理。常规的做法就是实例手势然后添加,程序员都是很懒的,并且我也一直比较喜欢东西都放在一起查找起来也方便。常规的声明和处理分开在代码量巨大的情形之下找起来还是略显麻烦,所以我将手势封装一下,方便使用

    . Demo地址

    API

    NS_ASSUME_NONNULL_BEGIN
    typedef void(^KJGestureRecognizerBlock)(UIView *view, UIGestureRecognizer *gesture);
    typedef NS_ENUM(NSUInteger, KJGestureType) {
        KJGestureTypeTap,       // 点击
        KJGestureTypeDouble,    // 双击
        KJGestureTypeLongPress, // 长按
        KJGestureTypeSwipe,     // 轻扫
        KJGestureTypePan,       // 移动
        KJGestureTypeRotate,    // 旋转
        KJGestureTypePinch,     // 缩放
    };
    static NSString * const _Nonnull KJGestureTypeStringMap[] = {
        [KJGestureTypeTap]       = @"UITapGestureRecognizer",
        [KJGestureTypeDouble]    = @"UITapGestureRecognizer",
        [KJGestureTypeLongPress] = @"UILongPressGestureRecognizer",
        [KJGestureTypeSwipe]     = @"UISwipeGestureRecognizer",
        [KJGestureTypePan]       = @"UIPanGestureRecognizer",
        [KJGestureTypeRotate]    = @"UIRotationGestureRecognizer",
        [KJGestureTypePinch]     = @"UIPinchGestureRecognizer",
    };
    
    @interface UIView (KJGestureBlock)
    /// 单击手势
    - (UIGestureRecognizer*)kj_AddTapGestureRecognizerBlock:(KJGestureRecognizerBlock)block;
    /// 手势处理
    - (UIGestureRecognizer*)kj_AddGestureRecognizer:(KJGestureType)type block:(KJGestureRecognizerBlock)block;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    使用示例

    _weakself;
    [self.displayImageView kj_AddTapGestureRecognizerBlock:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
        NSLog(@"单击");
    }];
    [self.displayImageView kj_AddGestureRecognizer:(KJGestureTypeDouble) block:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
        NSLog(@"双击");
    }];
    [self.displayImageView kj_AddGestureRecognizer:(KJGestureTypePan) block:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
        UIPanGestureRecognizer *panGestureRecognizer = (UIPanGestureRecognizer*)gesture;
        CGPoint translation = [panGestureRecognizer translationInView:panGestureRecognizer.view];
        NSLog(@"移动%.2f",translation.x);
    }];
    [self.displayImageView kj_AddGestureRecognizer:(KJGestureTypePinch) block:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
        UIPinchGestureRecognizer *pinchGestureRecognizer = (UIPinchGestureRecognizer*)gesture;
        NSLog(@"缩放%.2f,%.2f",weakself.lastScale,pinchGestureRecognizer.scale);
        switch (pinchGestureRecognizer.state) {
            case UIGestureRecognizerStateBegan:
            case UIGestureRecognizerStateChanged:{
                CGFloat scale = weakself.lastScale+pinchGestureRecognizer.scale-1;
                if (scale >= weakself.maxScale || scale <= weakself.minScale) {
                    return;
                }
                CGFloat w = kScreenW * scale;
                CGFloat h = kScreenH * scale;
                CGFloat x = weakself.originRect.origin.x - (kScreenW*(scale-1))/2.;
                CGFloat y = weakself.originRect.origin.y - (kScreenH*(scale-1))/2.;
                view.frame = CGRectMake(x, y, w, h);
            }
                break;
            case UIGestureRecognizerStateEnded:{
                CGFloat scale = weakself.lastScale+pinchGestureRecognizer.scale-1;
                if (scale >= weakself.maxScale) {
                    weakself.lastScale = weakself.maxScale;
                }else if (scale <= weakself.minScale) {
                    weakself.lastScale = weakself.minScale;
                }else{
                    weakself.lastScale += (pinchGestureRecognizer.scale-1);
                }
            }
                break;
            default:
                break;
        }
    }];
    

    简单介绍

    1. 开启视图的交换

    外界使用的时候也不需要再写该属性,又省一句代码- -|

    self.userInteractionEnabled = YES;
    
    2. 声明和添加

    这里提供七种手势枚举

    typedef NS_ENUM(NSUInteger, KJGestureType) {
        KJGestureTypeTap,       // 点击
        KJGestureTypeDouble,    // 双击
        KJGestureTypeLongPress, // 长按
        KJGestureTypeSwipe,     // 轻扫
        KJGestureTypePan,       // 移动
        KJGestureTypeRotate,    // 旋转
        KJGestureTypePinch,     // 缩放
    };
    static NSString * const _Nonnull KJGestureTypeStringMap[] = {
        [KJGestureTypeTap]       = @"UITapGestureRecognizer",
        [KJGestureTypeDouble]    = @"UITapGestureRecognizer",
        [KJGestureTypeLongPress] = @"UILongPressGestureRecognizer",
        [KJGestureTypeSwipe]     = @"UISwipeGestureRecognizer",
        [KJGestureTypePan]       = @"UIPanGestureRecognizer",
        [KJGestureTypeRotate]    = @"UIRotationGestureRecognizer",
        [KJGestureTypePinch]     = @"UIPinchGestureRecognizer",
    };
    

    NSClassFromString得到对应的手势类

    NSString *string = KJGestureTypeStringMap[type];
    __block UIGestureRecognizer *gesture = [[NSClassFromString(string) alloc] initWithTarget:self action:@selector(kGestureAction:)];
    [gesture setDelaysTouchesBegan:YES];
    [self addGestureRecognizer:gesture];
    
    3. 解决单击和双击共存问题
    if (type == KJGestureTypeTap) {
        [self.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer *recognizer, NSUInteger idx, BOOL *stop) {
            if ([recognizer isKindOfClass:[UITapGestureRecognizer class]] && ((UITapGestureRecognizer*)recognizer).numberOfTapsRequired == 2) {
                [gesture requireGestureRecognizerToFail:recognizer];
                *stop = YES;
            }
        }];
        string = [string stringByAppendingString:@"Tap"];
    }else if (type == KJGestureTypeDouble) {
        [(UITapGestureRecognizer*)gesture setNumberOfTapsRequired:2];
        [self.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer *recognizer, NSUInteger idx, BOOL *stop) {
            if ([recognizer isKindOfClass:[UITapGestureRecognizer class]] && ((UITapGestureRecognizer*)recognizer).numberOfTapsRequired == 1) {
                [recognizer requireGestureRecognizerToFail:gesture];
                *stop = YES;
            }
        }];
        string = [string stringByAppendingString:@"Double"];
    }
    
    4. 保存回调

    这里增加一个selectorString属性来区分不同的回调

    self.selectorString = string;
    self.gesrureblock = block;
    

    NSSelectorFromString 得到不同的回调

    #pragma mark - associated
    - (NSString*)selectorString{
        return objc_getAssociatedObject(self, @selector(selectorString));
    }
    - (void)setSelectorString:(NSString*)selectorString{
        objc_setAssociatedObject(self, @selector(selectorString), selectorString, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    - (KJGestureRecognizerBlock)gesrureblock{
        return (KJGestureRecognizerBlock)objc_getAssociatedObject(self, NSSelectorFromString(self.selectorString));
    }
    - (void)setGesrureblock:(KJGestureRecognizerBlock)gesrureblock{
        objc_setAssociatedObject(self, NSSelectorFromString(self.selectorString), gesrureblock, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    5. 处理手势
    - (void)kGestureAction:(UIGestureRecognizer*)gesture{
        NSString *string = NSStringFromClass([gesture class]);
        if ([gesture isKindOfClass:[UITapGestureRecognizer class]]) {
            if (((UITapGestureRecognizer*)gesture).numberOfTapsRequired == 1) {
                string = [string stringByAppendingString:@"Tap"];
            }else {
                string = [string stringByAppendingString:@"Double"];
            }
        }
        self.selectorString = string;
        self.gesrureblock(gesture.view, gesture);
    }
    
    备注:本文用到的部分函数方法和Demo,均来自三方库KJExtensionHandler,如有需要的朋友可自行pod 'KJExtensionHandler'引入即可

    视图UIView添加手势回调介绍就到此完毕,后面有相关再补充,写文章不容易,还请点个小星星传送门

    相关文章

      网友评论

          本文标题:iOS UIView添加手势回调

          本文链接:https://www.haomeiwen.com/subject/pefduktx.html