UIButton 扩大按钮的响应区域

320 阅读4分钟
原文链接: blog.csdn.net

在开发中有时会遇见设计图里按钮设计的特别小,这时会用到手动扩大UIButton的响应范围,下面有两个解决办法:

第一种方法:创建一个类目:UIButton+EnlargeTouchArea 

.h文件

  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface UIButton (EnlargeTouchArea)  
  4.   
  5. - (void)setEnlargeEdgeWithTop:(CGFloat) top right:(CGFloat) right bottom:(CGFloat) bottom  left:(CGFloat) left;  
  6.   
  7. - (void)setEnlargeEdge:(CGFloat) size;  
  8.   
  9. @end  
#import <UIKit/UIKit.h>

@interface UIButton (EnlargeTouchArea)

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

- (void)setEnlargeEdge:(CGFloat) size;

@end
.m文件
  1. //  
  2. //  UIButton+EnlargeTouchArea.m  
  3. //  HeBeiFM  
  4. //  
  5. //  Created by Apple on 16/4/27.  
  6. //  Copyright © 2016年 Apple. All rights reserved.  
  7. //  
  8.   
  9. #import "UIButton+EnlargeTouchArea.h"  
  10. #import <objc/runtime.h>  
  11.   
  12. @implementation UIButton (EnlargeTouchArea)  
  13.   
  14. static char topNameKey;  
  15. static char rightNameKey;  
  16. static char bottomNameKey;  
  17. static char leftNameKey;  
  18.   
  19. - (void)setEnlargeEdge:(CGFloat) size  
  20. {  
  21.     objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);  
  22.     objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);  
  23.     objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);  
  24.     objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);  
  25. }  
  26.   
  27. - (void) setEnlargeEdgeWithTop:(CGFloat) top right:(CGFloat) right  bottom:(CGFloat) bottom left:(CGFloat) left  
  28. {  
  29.     objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:top], OBJC_ASSOCIATION_COPY_NONATOMIC);  
  30.     objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:right], OBJC_ASSOCIATION_COPY_NONATOMIC);  
  31.     objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:bottom], OBJC_ASSOCIATION_COPY_NONATOMIC);  
  32.     objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:left], OBJC_ASSOCIATION_COPY_NONATOMIC);  
  33. }  
  34.   
  35. - (CGRect) enlargedRect  
  36. {  
  37.     NSNumber* topEdge = objc_getAssociatedObject(self, &topNameKey);  
  38.     NSNumber* rightEdge = objc_getAssociatedObject(self, &rightNameKey);  
  39.     NSNumber* bottomEdge = objc_getAssociatedObject(self, &bottomNameKey);  
  40.     NSNumber* leftEdge = objc_getAssociatedObject(self, &leftNameKey);  
  41.     if (topEdge && rightEdge && bottomEdge && leftEdge)  
  42.     {  
  43.         return CGRectMake(self.bounds.origin .x - leftEdge.floatValue,  
  44.                           self.bounds .origin.y - topEdge.floatValue,  
  45.                           self.bounds .size.width + leftEdge.floatValue + rightEdge.floatValue,  
  46.                           self.bounds .size.height + topEdge.floatValue + bottomEdge.floatValue);  
  47.     }  
  48.     else  
  49.     {  
  50.         return self.bounds;  
  51.     }  
  52. }  
  53.   
  54. - (UIView*) hitTest:(CGPoint) point withEvent:(UIEvent*) event  
  55. {  
  56.     CGRect rect = [self enlargedRect];  
  57.     if (CGRectEqualToRect(rect, self.bounds))  
  58.     {  
  59.         return [super hitTest:point withEvent:event];  
  60.     }  
  61.     return CGRectContainsPoint(rect, point) ? self : nil;  
  62. }  
  63.   
  64. @end  
//
//  UIButton+EnlargeTouchArea.m
//  HeBeiFM
//
//  Created by Apple on 16/4/27.
//  Copyright © 2016年 Apple. All rights reserved.
//

#import "UIButton+EnlargeTouchArea.h"
#import <objc/runtime.h>

@implementation UIButton (EnlargeTouchArea)

static char topNameKey;
static char rightNameKey;
static char bottomNameKey;
static char leftNameKey;

- (void)setEnlargeEdge:(CGFloat) size
{
    objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);
    objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);
    objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);
    objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (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

使用方法:
  1. UIButton *button = [UIButton new];  
  2. [button setEnlargeEdge:20];  
  3. //或者  
  4. [button setEnlargeEdgeWithTop:20 right:2 0 bottom:20 left:2 0];  
    UIButton *button = [UIButton new];
    [button setEnlargeEdge:20];
    //或者
    [button setEnlargeEdgeWithTop:20 right:20 bottom:20 left:20];


第二种:直接创建一个UIButton类,然后复写pointInside方法

使用时继承于此类即可

.h文件

  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface BiggerClickAreaButton : UIButton  
  4.   
  5. @end  
#import <UIKit/UIKit.h>

@interface BiggerClickAreaButton : UIButton

@end
.m文件
  1. #import "BiggerClickAreaButton.h"  
  2.   
  3. @implementation BiggerClickAreaButton  
  4.   
  5. - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event  
  6. {  
  7.     CGRect bounds = self.bounds;  
  8.     //若原热区小于44x44,则放大热区,否则保持原大小不变  
  9.     CGFloat widthDelta = MAX(44.0 - bounds .size.width, 0);  
  10.     CGFloat heightDelta = MAX(44.0 - bounds .size.height, 0);  
  11.     bounds = CGRectInset(bounds, -0.5 * widthDelta, -0 .5 * heightDelta);  
  12.     return CGRectContainsPoint(bounds, point);  
  13. }  
  14.   
  15.   
  16. @end  
#import "BiggerClickAreaButton.h"

@implementation BiggerClickAreaButton

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


@end
使用时直接继承创建即可