一、OC版
OC版使用:
[btn be_setEnlargeEdge:5];
[btn be_setEnlargeEdgeWithTop:10 right:5 bottom:5 left:10];
OC版实现:
//
// UIButton+BEEnlargeEdge.h
// TKApp
//
// Created by luopengfei on 2017/1/5.
// Copyright © 2017年 luopengfei. All rights reserved.
//
#import
@interface UIButton (BEEnlargeEdge)
/**
增大点击区域
@param size 上左下右的增大量
*/
- (void)be_setEnlargeEdge:(CGFloat)size;
/**
增大点击区域
@param size 上左下右的增大量
*/
- (void)be_setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left;
@end
//
// UIButton+BEEnlargeEdge.m
// TKApp
//
// Created by luopengfei on 2017/1/5.
// Copyright © 2017年 luopengfei. All rights reserved.
//
#import "UIButton+BEEnlargeEdge.h"
#import
@implementation UIButton (BEEnlargeEdge)
static char topNameKey;
static char rightNameKey;
static char bottomNameKey;
static char leftNameKey;
- (void)be_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)be_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)be_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;
}
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
CGRect rect = [self be_enlargedRect];
if (CGRectEqualToRect(rect, self.bounds)) {
return [super pointInside:point withEvent:event];
}
return CGRectContainsPoint(rect, point) ? YES : NO;
}
//- (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
二、swift版
swift版使用:
let btn = BEButton()
xxxx
btn.setEnlargeEdge(5)
btn.setEnlargeEdge(10, 5, 10, 5)
补充:由于BEButton继承UIButton,可以添加特有属性,使用objc_setAssociatedObject和objc_getAssociatedObject进行 关联 有些画蛇添足了。
//
// BEButton.swift
// ShuLian
//
// Created by 骆鹏飞 on 2018/5/4.
// Copyright © 2018 GXCJ. All rights reserved.
//
import UIKit
class BEButton: UIButton {
let _top = "_top"
let _left = "_left"
let _bottom = "_bottom"
let _right = "_right"
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let rect = enlargedRect()
if rect.equalTo(bounds) {
return super.point(inside: point, with: event)
}
return rect.contains(point) ? true : false
}
}
extension BEButton {
func setEnlargeEdge(_ length:Float) {
setEnlargeEdge(length, length, length, length)
}
func setEnlargeEdge(_ top:Float, _ left:Float, _ bottom:Float, _ right:Float) {
objc_setAssociatedObject(
self,
UnsafeRawPointer(bitPattern: _top.hashValue)!,
NSNumber(value: top),
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_setAssociatedObject(
self,
UnsafeRawPointer(bitPattern: _left.hashValue)!,
NSNumber(value: left),
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_setAssociatedObject(
self,
UnsafeRawPointer(bitPattern: _bottom.hashValue)!,
NSNumber(value: bottom),
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_setAssociatedObject(
self,
UnsafeRawPointer(bitPattern: _right.hashValue)!,
NSNumber(value: right),
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
private func enlargedRect() -> CGRect {
let topEdge = objc_getAssociatedObject(self, UnsafeRawPointer(bitPattern: _top.hashValue)!) as? NSNumber
let rightEdge = objc_getAssociatedObject(self, UnsafeRawPointer(bitPattern: _left.hashValue)!) as? NSNumber
let bottomEdge = objc_getAssociatedObject(self, UnsafeRawPointer(bitPattern: _bottom.hashValue)!) as? NSNumber
let leftEdge = objc_getAssociatedObject(self, UnsafeRawPointer(bitPattern: _right.hashValue)!) as? NSNumber
if ((topEdge != nil) && (leftEdge != nil) && (bottomEdge != nil) && (rightEdge != nil)) {
return CGRect(
x: bounds.origin.x - CGFloat(leftEdge!.floatValue),
y: bounds.origin.y - CGFloat(topEdge!.floatValue),
width: bounds.width + CGFloat(leftEdge!.floatValue) + CGFloat(rightEdge!.floatValue),
height: bounds.height + CGFloat(topEdge!.floatValue) + CGFloat(bottomEdge!.floatValue))
} else {
return self.bounds
}
}
}
原理:重写pointInside: withEvent:方法,改变判断点击的区域是否在某个视图中的逻辑。
虽然对UIButton做extension会使用更方便,但无形中会增加许多性能消耗,而且很容易与其他的extension冲突。所以建议写一个专门扩大相应区域的Button类,类似BEButton,有需要时就使用。