RunTime动态扩大UIControl及其子类按钮点击区域

此文章是通过添加UIControl分类使用RunTime实现UIControl+AddClickRect.h
UIControl+AddClickRect.h文件代码如下

//动态扩大UIControl及其子类的点击范围

#import 

@interface UIControl (AddClickRect)

/**
 UIEdgeInsetsMake(-3, -4, -5, -6). 表示扩大顺序为上左下右
 self.control.addEdge = UIEdgeInsetsMake(-3, -4, -5, -6);
 */
@property(nonatomic, assign) UIEdgeInsets addEdge;

/**
 self.control.addFourEdges = 3.0;
 */
@property(nonatomic, assign) CGFloat addFourEdges;

/*
 self.control.addWidthEdge = 3.0;
 */
@property(nonatomic, assign) CGFloat addWidthEdge;

/*
 self.control.addHeightEdge = 3.0;
 */
@property(nonatomic, assign) CGFloat addHeightEdge;


@end

UIControl+AddClickRect.h文件代码如下



#import "UIControl+AddClickRect.h"
#import 

static const char * kAddEdge = "addEdge";
static const char * kAddFourEdges      = "addFourEdges";
static const char * kAddWidthEdge    = "addWidthEdge";
static const char * kAddHeightEdge   = "addHeightEdge";

@implementation UIControl (AddClickRect)

///MARK: 私有方法
-(void)setAddEdge:(UIEdgeInsets)addEdge{
    NSValue *value = [NSValue value:&addEdge withObjCType:@encode(UIEdgeInsets)];
    objc_setAssociatedObject(self,kAddEdge, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(void)setAddFourEdges:(CGFloat)addFourEdges{
    CGFloat width = self.bounds.size.width * addFourEdges;
    CGFloat height = self.bounds.size.height * addFourEdges;
    self.addEdge = UIEdgeInsetsMake(-height, -width,-height, -width);
    objc_setAssociatedObject(self, kAddFourEdges, @(addFourEdges), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(void)setAddWidthEdge:(CGFloat)addWidthEdge{
    CGFloat width = self.bounds.size.width * addWidthEdge;
    CGFloat height = self.bounds.size.height ;
    self.addEdge = UIEdgeInsetsMake(-height, -width,-height, -width);
    objc_setAssociatedObject(self, kAddWidthEdge, @(addWidthEdge), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(void)setAddHeightEdge:(CGFloat)addHeightEdge{
    CGFloat width = self.bounds.size.width;
    CGFloat height = self.bounds.size.height * addHeightEdge ;
    self.addEdge = UIEdgeInsetsMake(-height, -width,-height, -width);
    objc_setAssociatedObject(self, kAddHeightEdge, @(addHeightEdge), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

///MARK: 获取点击区域
-(UIEdgeInsets)addEdge{
    NSValue *value = objc_getAssociatedObject(self, kAddEdge);
    UIEdgeInsets edgeInsets;
    [value getValue:&edgeInsets];
    return value ? edgeInsets:UIEdgeInsetsZero;
}

-(CGFloat)addFourEdges{
    return [objc_getAssociatedObject(self, kAddFourEdges) floatValue];
}

-(CGFloat)addWidthEdge{
    return [objc_getAssociatedObject(self, kAddWidthEdge) floatValue];
}

-(CGFloat)addHeightEdge{
    return [objc_getAssociatedObject(self, kAddHeightEdge) floatValue];
}

///MARK: 重写 pointInside 方法
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    //如果  边界值无变化  失效 隐藏 或者透明 直接返回
    if(UIEdgeInsetsEqualToEdgeInsets(self.addEdge, UIEdgeInsetsZero) || !self.enabled || self.hidden || self.alpha == 0 ) {
        return [super pointInside:point withEvent:event];
    }else{
        CGRect relativeFrame = self.bounds;
        CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.addEdge);
        return CGRectContainsPoint(hitFrame, point);
    }
}
@end

你可能感兴趣的:(RunTime动态扩大UIControl及其子类按钮点击区域)