此文章是通过添加UIControl分类使用RunTime实现UIControl+AddClickRect.h
UIControl+AddClickRect.h文件代码如下
//动态扩大UIControl及其子类的点击范围
#import <UIKit/UIKit.h>
@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 <objc/runtime.h>
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