您的位置:首页 > 移动开发 > IOS开发

button扩大可点击范围

2017-02-24 14:19 260 查看
一个扩大按钮点击范围的小技巧,在不改变frame的前提下,可通过以下方法实现:

关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分。

在类的定义之外为类增加额外的存储空间

    使用关联,我们可以不用修改类的定义而为其对象增加存储空间。这在我们无法访问到类的源码的时候或者是考虑到二进制兼容性的时候是非常有用。
    关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个都使用不同的关键字即可。关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不会导致资源不可回收)。

创建关联

    创建关联要使用到Objective-C的运行时函数:objc_setAssociatedObject来把一个对象与另外一个对象进行关联。该函数需要四个参数:

源对象,关键字,关联的对象和一个关联策略。
  ■  关键字是一个void类型的指针。每一个关联的关键字必须是唯一的。通常都是会采用静态变量来作为关键字。
  ■  关联策略表明了相关的对象是通过赋值,保留引用还是复制的方式进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。这种关联策略是通过使用预先定义好的常量来表示的。

获取相关联的对象

    获取相关联的对象时使用Objective-C函数objc_getAssociatedObject。

断开关联

    断开关联是使用objc_setAssociatedObject函数,传入nil值即可。

使用函数objc_removeAssociatedObjects可以断开所有关联。通常情况下不建议使用这个函数,因为他会断开所有关联。只有在需要把对象恢复到“原始状态”的时候才会使用这个函数。

下面是例子:

@implementation UIButton(extend)

static char topNameKey;

static char rightNameKey;

static char bottomNameKey;

static char leftNameKey;

-(void)setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom
left:(CGFloat)left{

    objc_setAssociatedObject(self, &topNameKey,
[NSNumber
numberWithFloat:top], OBJC_ASSOCIATION_COPY_NONATOMIC);

    objc_setAssociatedObject(self, &rightNameKey,
[NSNumber
numberWithFloat:right],
OBJC_ASSOCIATION_COPY_NONATOMIC<
d5b2
span style="color:#000000;">);

    objc_setAssociatedObject(self, &bottomNameKey,
[NSNumber
numberWithFloat:bottom],
OBJC_ASSOCIATION_COPY_NONATOMIC);

    objc_setAssociatedObject(self, &leftNameKey,
[NSNumber
numberWithFloat:left], OBJC_ASSOCIATION_COPY_NONATOMIC);

}

-(CGRect)enlargedRect{

    NSNumber *topEdge =
objc_getAssociatedObject(self, &topNameKey);

    NSNumber *rightEdge =
objc_getAssociatedObject(self, &rightNameKey);

    NSNumber *bottomEdge =
objc_getAssociatedObject(self, &bottomNameKey);

    NSNumber *leftEdge =
objc_getAssociatedObject(self, &leftNameKey);

    

    CGRect rect =
CGRectZero;

    

    if(topEdge && rightEdge && bottomEdge && leftEdge){

        rect = CGRectMake(self.bounds.origin.x-leftEdge.floatValue,
self.bounds.origin.y-topEdge.floatValue,
self.bounds.size.width+leftEdge.floatValue+rightEdge.floatValue,
self.bounds.size.height+topEdge.floatValue+bottomEdge.floatValue);

    }else{

        rect = self.bounds;

    }

    

    return rect;

}

-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event{

    CGRect rect = [self
enlargedRect];

    if(CGRectEqualToRect(rect,
self.bounds)){

        return [super
hitTest:point withEvent:event];

    }

    return
CGRectContainsPoint(rect, point) ?
self : nil;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息