网上也看了一些文章,大部分都是扩大UIButton的点击区域,做法是
- 自定义一个子类继承自UIButton,重写 pointInside 方法
- 给UIButton添加一个分类,分类覆盖原有类的 pointInside 方法
但是实际上,除了UIButton外,UIImageView,UILable,甚至UIIView都可能有增加触摸区域的需求,难道都要一个一个去继承吗? 可以自定义一个UIView的子类去实现,然后这些控件再继承这个子类,但是这种做法耦合性太强了,我更喜欢面向切面的方式
// QYExchangeRecordController.h
#import <UIKit/UIKit.h>
@interface UIView (QYExpandResponseArea)
- (void)expandResponseAreaBounds:(UIEdgeInsets)outset ; /**< 扩大点击事件的响应区域*/
@end
// UIView+QYExpandResponseArea.m
#import "UIView+QYExpandResponseArea.h"
#import <objc/runtime.h>
@implementation UIView (QYExpandResponseArea)
+ (void)load {
//获取替换后的实例方法
Method newMethod = class_getInstanceMethod([self class], @selector(qy_pointInside:withEvent:));
//获取替换前的实例方法
Method origMethod = class_getInstanceMethod([self class], @selector(pointInside:withEvent:));
//然后交换实例方法
method_exchangeImplementations(newMethod, origMethod);
}
static char expandSizeKey;
- (void)expandResponseAreaBounds:(UIEdgeInsets)outset{
//OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
//OBJC_EXPORT 打包lib时,用来说明该函数是暴露给外界调用的。
//id object 表示关联者,是一个对象
//id value 表示被关联者,可以理解这个value最后是关联到object上的
//const void *key 被关联者也许有很多个,所以通过key可以找到指定的那个被关联者
objc_setAssociatedObject(self, &expandSizeKey, [NSValue valueWithUIEdgeInsets:outset], OBJC_ASSOCIATION_COPY_NONATOMIC);
}
//获取设置的扩大size,来扩大button的rect
//当前只是设置了一个扩大的size,当然也可以设置4个扩大的size,上下左右,具体扩大多少对应button的四个边传入对应的size
- (CGRect)expandRect {
NSValue *outsetValue = objc_getAssociatedObject(self, &expandSizeKey);
UIEdgeInsets outset = outsetValue.UIEdgeInsetsValue;
//
if (outsetValue) {
return CGRectMake(self.bounds.origin.x - outset.left,
self.bounds.origin.y - outset.top,
self.bounds.size.width + outset.left + outset.right,
self.bounds.size.height + outset.top + outset.bottom);
} else {
return self.bounds;
}
}
//响应用户的点击事件
- (BOOL)qy_pointInside:(CGPoint)point withEvent:(UIEvent *)event {
CGRect expandedRect = [self expandRect];
if (CGRectEqualToRect(expandedRect, self.bounds)) {
return [self qy_pointInside:point withEvent:event];
}
return CGRectContainsPoint(expandedRect, point) ? YES : NO;
}
@end
网友评论