UIButton 扩大点击范围
引言:
重写一个 Button 类,这个 button 类继承 UIButton ,重写- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event;
方法中修改 bounds 的值就可以就可以实现扩大按钮的点击区域。
# 一. 实现方式
自定义一个继承自 UIButton 的 LCScopeButton 类:
# 1. LCScopeButton.h
#import <UIKit/UIKit.h>
@interface LCScopeButton : UIButton
/** 单一方向扩大范围类型 */
typedef enum _LCOneWayScopeType {
LCOneWayScopeTypeHorizontal = 1, // 水平方向
LCOneWayScopeTypeVertical = 2, // 竖直方向
LCOneWayScopeTypeTop = 3, // 向上扩大
LCOneWayScopeTypeLeft = 4, // 向左扩大
LCOneWayScopeTypeBottom = 5, // 向下扩大
LCOneWayScopeTypeRight = 6 // 向右扩大
} LCOneWayScopeType;
/** xy轴双向扩大范围类型 */
typedef enum _LCTwoWayScopeType {
LCTwoWayScopeTypeAllAround = 1, // 四周
LCTwoWayScopeTypeUPLEFT = 2, // 左上
LCTwoWayScopeTypeLOWERLEFT = 3, // 左下
LCTwoWayScopeTypeUPRIGHT = 4, // 右上
LCTwoWayScopeTypeLOWERRIGHT = 5 // 右下
} LCTwoWayScopeType;
/**
* 设置 单一方向的点击范围 scopetype:方向类型 range:扩大或缩小距离
*/
-(void)lc_setOneWayClickScopeWithType:(LCOneWayScopeType)scopetype range:(CGFloat)range;
/**
* 设置 xy轴的点击范围 rangeX:X轴扩大或缩小距离 rangeY:Y轴扩大或缩小距离
*/
-(void)lc_setTwoWayClickScopeWithType:(LCTwoWayScopeType)scopetype rangeX:(CGFloat)rangeX rangeY:(CGFloat)rangeY;
# 2. LCScopeButton.m
#import "LCScopeButton.h"
@interface LCScopeButton ()
/** 范围 */
@property (nonatomic, assign) CGSize scopeSize;
/** 单一方向扩大范围类型 */
@property (nonatomic, assign) LCOneWayScopeType oneWayscopeType;
/** xy轴双向扩大范围类型 */
@property (nonatomic, assign) LCTwoWayScopeType twoWayscopeType;
@end
@implementation LCScopeButton
/**
* 设置 单一方向的点击范围 scopetype:方向类型 range:扩大或缩小距离
*/
-(void)lc_setOneWayClickScopeWithType:(LCOneWayScopeType)scopetype range:(CGFloat)range{
switch (scopetype) {
case LCOneWayScopeTypeHorizontal: // 水平
self.scopeSize = CGSizeMake(range, 0);
self.oneWayscopeType = LCOneWayScopeTypeHorizontal;
break;
case LCOneWayScopeTypeVertical: // 竖直
self.scopeSize = CGSizeMake(0, range);
self.oneWayscopeType = LCOneWayScopeTypeVertical;
break;
case LCOneWayScopeTypeTop: // 向上
self.scopeSize = CGSizeMake(0, range);
self.oneWayscopeType = LCOneWayScopeTypeTop;
break;
case LCOneWayScopeTypeLeft: // 向左
self.scopeSize = CGSizeMake(range, 0);
self.oneWayscopeType = LCOneWayScopeTypeLeft;
break;
case LCOneWayScopeTypeBottom: // 向下
self.scopeSize = CGSizeMake(0, range);
self.oneWayscopeType = LCOneWayScopeTypeBottom;
break;
case LCOneWayScopeTypeRight: // 向右
self.scopeSize = CGSizeMake(range, 0);
self.oneWayscopeType = LCOneWayScopeTypeRight;
break;
default:
break;
}
}
/**
* 设置 xy轴的点击范围 rangeX:X轴扩大或缩小距离 rangeY:Y轴扩大或缩小距离
*/
-(void)lc_setTwoWayClickScopeWithType:(LCTwoWayScopeType)scopetype rangeX:(CGFloat)rangeX rangeY:(CGFloat)rangeY{
self.scopeSize = CGSizeMake(rangeX, rangeY);
switch (scopetype) {
case LCTwoWayScopeTypeAllAround: // 四周
self.twoWayscopeType = LCTwoWayScopeTypeAllAround;
break;
case LCTwoWayScopeTypeUPLEFT: // 左上
self.twoWayscopeType = LCTwoWayScopeTypeUPLEFT;
break;
case LCTwoWayScopeTypeLOWERLEFT: // 左下
self.twoWayscopeType = LCTwoWayScopeTypeLOWERLEFT;
break;
case LCTwoWayScopeTypeUPRIGHT: // 右上
self.twoWayscopeType = LCTwoWayScopeTypeUPRIGHT;
break;
case LCTwoWayScopeTypeLOWERRIGHT: // 右下
self.twoWayscopeType = LCTwoWayScopeTypeLOWERRIGHT;
break;
default:
break;
}
}
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
// 获取当前视图的 bounds
CGRect bounds = self.bounds;
CGFloat scopeX = self.scopeSize.width;
CGFloat scopeY = self.scopeSize.height;
CGFloat boundsW = self.bounds.size.width;
CGFloat boundsH = self.bounds.size.height;
if (self.oneWayscopeType != 0) {
switch (self.oneWayscopeType) {
case LCOneWayScopeTypeHorizontal: // 水平
bounds = CGRectInset(bounds, -scopeX, 0);
break;
case LCOneWayScopeTypeVertical: // 竖直
bounds = CGRectInset(bounds, 0, -scopeY);
break;
case LCOneWayScopeTypeTop: // 向上
bounds = CGRectMake(0, -scopeY/2, boundsW, boundsH);
bounds = CGRectInset(bounds, 0, -scopeY/2);
break;
case LCOneWayScopeTypeLeft: // 向左
bounds = CGRectMake(-scopeX/2, 0, boundsW, boundsH);
bounds = CGRectInset(bounds, -scopeX/2, 0);
break;
case LCOneWayScopeTypeBottom: // 向下
bounds = CGRectMake(0, scopeY/2, boundsW, boundsH);
bounds = CGRectInset(bounds, 0, -scopeY/2);
break;
case LCOneWayScopeTypeRight: // 向右
bounds = CGRectMake(scopeX/2, 0, boundsW, boundsH);
bounds = CGRectInset(bounds, -scopeX/2, 0);
break:
default:
break;
}
}
if (self.twoWayscopeType != 0) {
switch (self.twoWayscopeType) {
case LCTwoWayScopeTypeAllAround: // 四周
bounds = CGRectInset(bounds, -scopeX, -scopeY);
break;
case LCTwoWayScopeTypeUPLEFT: // 左上
bounds = CGRectMake(-scopeX/2, -scopeY/2, boundsW, boundsH);
bounds = CGRectInset(bounds, -scopeX/2, -scopeY/2);
break;
case LCTwoWayScopeTypeLOWERLEFT: // 左下
bounds = CGRectMake(-scopeX/2, scopeY/2, boundsW, boundsH);
bounds = CGRectInset(bounds, -scopeX/2, -scopeY/2);
break;
case LCTwoWayScopeTypeUPRIGHT: // 右上
bounds = CGRectMake(scopeX/2, -scopeY/2, boundsW, boundsH);
bounds = CGRectInset(bounds, -scopeX/2, -scopeY/2);
break;
case LCTwoWayScopeTypeLOWERRIGHT: // 右下
bounds = CGRectMake(scopeX/2, scopeY/2, boundsW, boundsH);
bounds = CGRectInset(bounds, -scopeX/2, -scopeY/2);
break;
default:
break;
}
}
return CGRectContainsPoint(bounds, point);
}