通过扩展属性实现增大UIButton的frame外点击范围
开发中总是遇到测试反馈小图标按钮点击没反应的问题,不是没反应是设计的太小了,真是太小了,此时就会提看起来小用起来大的要求,安排!
Swift版
import Foundation
import UIKit
extension UIButton {
// 增加点击边距的扩展属性
private struct HitEdgeInsetsAssociatedKeys {
static var hitTestEdgeInsets: UIEdgeInsets = .zero
}
@objc var hitTestEdgeInsets: UIEdgeInsets {
get {
return objc_getAssociatedObject(self, &HitEdgeInsetsAssociatedKeys.hitTestEdgeInsets) as! UIEdgeInsets
}
set(newValue) {
objc_setAssociatedObject(self, &HitEdgeInsetsAssociatedKeys.hitTestEdgeInsets, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
open override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
if self.hitTestEdgeInsets == UIEdgeInsets.zero || !self.isEnabled || self.isHidden {
return super.point(inside: point, with: event)
}
let relativeFrame = self.bounds
let hitFrame = relativeFrame.inset(by: self.hitTestEdgeInsets);
return CGRectContainsPoint(hitFrame, point);
}
}
使用
yourButton.hitTestEdgeInsets = UIEdgeInsetsMake(-20, -20, -20, -10)
OC版
UIButton+HitEdgeInsets.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIButton (HitEdgeInsets)
@property (nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;
@end
NS_ASSUME_NONNULL_END
import "UIButton+HitEdgeInsets.m
#import "UIButton+HitEdgeInsets.h"
@implementation UIButton (HitEdgeInsets)
@dynamic hitTestEdgeInsets;
static const NSString *Associated_KEY_HIT_TEST_EDGE_INSETS = @"HitTestEdgeInsets";
- (void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets {
NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:@encode(UIEdgeInsets)];
objc_setAssociatedObject(self, &Associated_KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIEdgeInsets)hitTestEdgeInsets {
NSValue *value = objc_getAssociatedObject(self, &Associated_KEY_HIT_TEST_EDGE_INSETS);
if(value) {
UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets;
}else {
return UIEdgeInsetsZero;
}
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || !self.enabled || self.hidden) {
return [super pointInside:point withEvent:event];
}
CGRect relativeFrame = self.bounds;
CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets);
return CGRectContainsPoint(hitFrame, point);
}
@end