美文网首页
通过runtime机制扩大UIButton的点击热区

通过runtime机制扩大UIButton的点击热区

作者: 程序媛vivid | 来源:发表于2018-11-08 16:52 被阅读6次

GitHub地址:UIButton-EnlargeEdge


情景描述

根据苹果的推荐,按钮的热区设置不小于44x44pt。当一些需要点击的按钮太小难以被用户点击时,就需要我们扩大热区来优化用户体验了。


实现思路:

一,通过重写UIButton的内部方法- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event实现:

 - (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);
 }

二,通过运行时机制实现,利用 objective-c 中的 objc_setAssociatedObject 来记录热区范围,通过- (UIView)hitTest:(CGPoint) point withEvent:(UIEvent) event扩大热区范围:

#import <UIKit/UIKit.h>
#import <objc/runtime.h>
@interface UIButton (EnlargeEdge)
- (void)setEnlargeEdge:(CGFloat) size;
- (void)setEnlargeEdgeWithTop:(CGFloat) top right:(CGFloat) right bottom:(CGFloat) bottom left:(CGFloat) left;
@end

具体看看实现文件

#import "UIButton+EnlargeEdge.h"
@implementation UIButton (EnlargeEdge)
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
使用方法:
 [_btn setEnlargeEdgeWithTop:15 right:10 bottom:10 left:15];
 [_btn setEnlargeEdge:20];

相关文章

网友评论

      本文标题:通过runtime机制扩大UIButton的点击热区

      本文链接:https://www.haomeiwen.com/subject/guiwxqtx.html