iOS扩大UIButton按钮的可点击区域

一、开发中遇到的问题

我们在开发时有时遇到这中情况:UI给的图片很小,button的点击区域要求比较大。如果用 setBackgroundImage: 方式设置图片会导致图片也跟着button的frame放大,如果使用 setImage: 设置图片,图片虽然不会跟着button的frame 发生变化,但是想要调整好图片显示的位置确很麻烦。

二、分析解决方法

因此最好的办法就是:设置button的大小刚好就是图片的大小,此时再调整图片frame的时候就非常方便了 (button的frame就是图片的frame)。接下来要解决的问题就是扩大button的点击区域。

三、解决方案

1、在原来button的基础上再添加一个透明的大button(不推荐)

2、继承 UIButton 然后重写 pointInside:(CGPoint)point withEvent:(UIEvent *)event 方法

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGRect bounds = self.bounds;
    // 若原热区小于44x44,则放大热区,否则保持原大小不变
    CGFloat deltaW = MAX(44 - bounds.size.width, 0);
    CGFloat deltaH = MAX(44 - bounds.size.height, 0);
    bounds = CGRectInset(bounds, -deltaW * 0.5, -deltaH * 0.5);
    return CGRectContainsPoint(bounds, point);
}

使用:

    ZHButton *btn = [[ZHButton alloc] initWithFrame:CGRectMake(100, 100, 20, 20)];
    [btn addTarget:self action:@selector(log) forControlEvents:UIControlEventTouchUpInside];
    btn.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:btn];

虽然button 的宽和高都只有 20 但是按钮能响应点击的热点区域却在原点击区域基础上上下左右各扩展了 (44 - 20)/ 2 = 21 .如此一来button 的可点击区域就非常大了,而且button 的frame也没有受到影响。

3、给button添加一个分类,使用对象关联设置button 的热点区域

其实其思路和方法二一致,不过使用起来更方便了。

.h 文件

@interface UIButton (EnlargeArea)

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

@end

.m 文件

#import <objc/runtime.h>
@implementation UIButton (EnlargeArea)
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);
    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);
    if (topEdge && rightEdge && bottomEdge && leftEdge) {
        return 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 {
        return self.bounds;
    }
}


- (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;
}
@end

以上就是button扩大可点击区域的3种方法,个人推荐第三种,使用简单方便。

 

posted on 2016-04-05 23:11  &#127774;Bob  阅读(321)  评论(0编辑  收藏  举报

导航