通過runtime機制擴大UIButton的點擊熱區(qū)

GitHub地址:UIButton-EnlargeEdge


情景描述

根據(jù)蘋果的推薦,按鈕的熱區(qū)設置不小于44x44pt。當一些需要點擊的按鈕太小難以被用戶點擊時,就需要我們擴大熱區(qū)來優(yōu)化用戶體驗了。


實現(xiàn)思路:

一,通過重寫UIButton的內部方法- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event實現(xiàn):

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event{
  CGRect bounds = self.bounds;
 
 //若原熱區(qū)小于44x44,則放大熱區(qū),否則保持原大小不變
   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);
 }

二,通過運行時機制實現(xiàn),利用 objective-c 中的 objc_setAssociatedObject 來記錄熱區(qū)范圍,通過- (UIView)hitTest:(CGPoint) point withEvent:(UIEvent) event擴大熱區(qū)范圍:

#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

具體看看實現(xiàn)文件

#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];
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容