1、前景
- 在开发中我们经常会遇到这种情况,UI给了我们一个比较小的按钮图标,我们如果设置按钮的大小和图标一样那么可点击区域也就会比较小,用户体验并不好。
2、传统做法
- 创建了一个新的按钮,改变按钮的热区(可点击区域),
- 然后在创建按钮的时候都继承自此按钮。
- 但是这样并没有改变按钮的大小,只是改变了按钮的热区(可点击区域)。
- 个人觉得这样做不是很灵活,于是受启发为按钮写了一个分类。并将热区扩大的比例作为按钮的一个属性。
3、代码
//
// 文 件 名:UIButton+TouchArea.h
//
// 版权所有:Copyright © 2020 DSY. All rights reserved.
// 创 建 者:CH520
// 创建日期:2020/5/3.
// 文档说明:
// 修 改 人:
// 修改日期:
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIButton (TouchArea)
// 扩大按钮热区的比例系数(曲线救国)
@property (nonatomic, copy) NSString *clickArea;
@end
NS_ASSUME_NONNULL_END
//
// 文 件 名:UIButton+TouchArea.m
//
// 版权所有:Copyright © 2020 DSY. All rights reserved.
// 创 建 者:CH520
// 创建日期:2020/5/3.
// 文档说明:
// 修 改 人:
// 修改日期:
//
#import "UIButton+TouchArea.h"
#import <objc/runtime.h>
@implementation UIButton (TouchArea)
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
[super pointInside:point withEvent:event];
// 获取bounds 实际大小
CGRect bounds = self.bounds;
if (self.clickArea) {
CGFloat area = [self.clickArea floatValue];
CGFloat widthDelta = MAX(area * bounds.size.width - bounds.size.width, .0);
CGFloat heightDelta = MAX(area * bounds.size.height - bounds.size.height, .0);
//扩大bounds
bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);
}
// 点击的点在新的bounds 中 就会返回YES
return CGRectContainsPoint(bounds, point);
}
- (void)setClickArea:(NSString *)clickArea {
objc_setAssociatedObject(self, @selector(clickArea), clickArea, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)clickArea {
return objc_getAssociatedObject(self, @selector(clickArea));
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *redBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:redBtn];
redBtn.frame = CGRectMake(150, 150, 50, 50);
// 这里就是按钮的实际可点击区域大小,可点击面积等效于按钮的尺寸乘以该参数
redBtn.clickArea = @"10";
redBtn.backgroundColor = [UIColor redColor];
[redBtn addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside];
}
- (void)clickBtn {
NSLog(@"被点击了...");
}
@end