美文网首页
iOS扩大按钮响应范围

iOS扩大按钮响应范围

作者: 咕噜_LSP | 来源:发表于2019-02-20 15:17 被阅读0次

    原理:重写view的下面任一方法

    //寻找合适的view
     - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    //判断点是否在视图上
    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
    

    法一

    要利用runTime创建类别私有属性

    附上view的拓展类代码:

    @interface UIButton (EnlargeTouchArea)
    
    - (void)enlargeTouchEdge:(UIEdgeInsets)edge;
    
    @end
    
    #import "UIButton+EnlargeTouchArea.h"
    #import <objc/runtime.h>
    
    @implementation UIButton (EnlargeTouchArea)
    
    
    static char edgeKey;
    
    - (NSString *)enlargeEdge {
        return objc_getAssociatedObject(self, &edgeKey);
    }
    
    - (void)enlargeTouchEdge:(UIEdgeInsets)edge {
        NSString *edgeStr = NSStringFromUIEdgeInsets(edge);
        objc_setAssociatedObject(self, &edgeKey, edgeStr, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        UIEdgeInsets changeInsets = UIEdgeInsetsFromString([self enlargeEdge]);
        CGFloat x = self.bounds.origin.x + changeInsets.left;
        CGFloat y = self.bounds.origin.y + changeInsets.top;
        CGFloat width = self.bounds.size.width - changeInsets.left - changeInsets.right;
        CGFloat height = self.bounds.size.height - changeInsets.top - changeInsets.bottom;
        CGRect rect = CGRectMake(x, y, width, height);
        
        if (CGRectEqualToRect(rect, self.bounds)) {
            return [super hitTest:point withEvent:event];
        }
        return CGRectContainsPoint(rect, point) ? self : nil;
    }
    
    //- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    //    UIEdgeInsets changeInsets = UIEdgeInsetsFromString([self enlargeEdge]);
    //    if (changeInsets.top != 0 || changeInsets.left != 0 || changeInsets.bottom != 0 || changeInsets.right !=0) {
    //        CGRect myBounds = self.bounds;
    //        myBounds.origin.x = myBounds.origin.x + changeInsets.left;
    //        myBounds.origin.y = myBounds.origin.y + changeInsets.top;
    //        myBounds.size.width = myBounds.size.width - changeInsets.left - changeInsets.right;
    //        myBounds.size.height = myBounds.size.height - changeInsets.top - changeInsets.bottom;
    //        return CGRectContainsPoint(myBounds, point);
    //    }else {
    //        return CGRectContainsPoint(self.bounds, point);
    //    }
    //}
    
    @end
    

    使用

    - (void)viewDidLoad {
       [super viewDidLoad];
       // Do any additional setup after loading the view, typically from a nib.
       
       UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
       btn.frame = CGRectMake(150, 200, 200, 200);
       btn.backgroundColor = [UIColor redColor];
       [btn addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];
       [self.view addSubview:btn];
    //...
       [btn enlargeTouchEdge:UIEdgeInsetsMake(-50, -50, -50, -50)];
    }
    
    - (void)btnAction {
       NSLog(@"tap");
    }
    

    法二

    直接创建一个UIButton类,然后复写pointInside\hitTest方法,使用时继承于此类即可
    附上UIButton类代码:

    @interface EnlargeTouchAreaButton : UIButton
    @property (nonatomic, assign) UIEdgeInsets changeInsets;
    
    @end
    
    
    #import "EnlargeTouchAreaButton.h"
    
    @implementation EnlargeTouchAreaButton
    
    - (void)setChangeInsets:(UIEdgeInsets)changeInsets {
        _changeInsets = changeInsets;
    }
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        CGFloat x = self.bounds.origin.x + self.changeInsets.left;
        CGFloat y = self.bounds.origin.y + self.changeInsets.top;
        CGFloat width = self.bounds.size.width - self.changeInsets.left - self.changeInsets.right;
        CGFloat height = self.bounds.size.height - self.changeInsets.top - self.changeInsets.bottom;
        CGRect rect = CGRectMake(x, y, width, height);
        
        if (CGRectEqualToRect(rect, self.bounds)) {
            return [super hitTest:point withEvent:event];
        }
        return CGRectContainsPoint(rect, point) ? self : nil;
    }
    
    //- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    //    if (self.changeInsets.top != 0 || self.changeInsets.left != 0 || self.changeInsets.bottom != 0 || self.changeInsets.right !=0) {
    //        CGRect myBounds = self.bounds;
    //        myBounds.origin.x = myBounds.origin.x + self.changeInsets.left;
    //        myBounds.origin.y = myBounds.origin.y + self.changeInsets.top;
    //        myBounds.size.width = myBounds.size.width - self.changeInsets.left - self.changeInsets.right;
    //        myBounds.size.height = myBounds.size.height - self.changeInsets.top - self.changeInsets.bottom;
    //        return CGRectContainsPoint(myBounds, point);
    //    }else {
    //        return CGRectContainsPoint(self.bounds, point);
    //    }
    //}
    
    @end
    

    使用

    EnlargeTouchAreaButton *btn2 = [EnlargeTouchAreaButton buttonWithType:UIButtonTypeCustom];
        btn2.frame = CGRectMake(150, 200, 200, 200);
        btn2.backgroundColor = [UIColor redColor];
        [btn2 addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:btn2];
        btn2.changeInsets = UIEdgeInsetsMake(-50, -50, -50, -50);
    

    参考(https://blog.csdn.net/u013282507/article/details/51259598

    相关文章

      网友评论

          本文标题:iOS扩大按钮响应范围

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