简介:
以前UITabbar使用中间有一个凸起按钮时,常常就需要用到hitTest来处理可点击的范围。
示例代码:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *hitView = nil; //NSLog(@"point:%@", NSStringFromCGPoint(point)); UIButton *roundBtn = (UIButton *)[self viewWithTag:10086]; UIButton *leftBtn = (UIButton *)[self viewWithTag:10087]; UIButton *rightBtn = (UIButton *)[self viewWithTag:10088]; BOOL pointInRound = [self touchPointInsideCircle:roundBtn.center radius:30 targetPoint:point]; if (pointInRound) { hitView = roundBtn; } else if(CGRectContainsPoint(leftBtn.frame, point)) { hitView = leftBtn; } else if(CGRectContainsPoint(rightBtn.frame, point)) { hitView = rightBtn; } else { hitView = self; } return hitView; }
增加categ,可以拓展按钮的点击范围:
#import <UIKit/UIKit.h> @interface UIButton (EnlargeTouchArea) /** * 扩大 UIButton 的點擊範圍 * 控制上下左右的延長範圍 * * @param top <#top description#> * @param right <#right description#> * @param bottom <#bottom description#> * @param left <#left description#> */ - (void)setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left; @end
#import "UIButton+Category.h" #import <objc/runtime.h> @implementation UIButton (EnlargeTouchArea) static char topNameKey; static char rightNameKey; static char bottomNameKey; static char leftNameKey; - (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
另一种实现方式:扩大按钮的点击区域
要扩大UIButton的点击事件响应范围,只需要重写UIButton的hitTest方法
//将点击事件响应范围扩大到周边20个点 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { CGRect rect = self.frame; //新的响应事件的区域 //这里的区域是在父控件坐标系内的 rect.origin.x -= 20; rect.origin.y -= 20; rect.size.height += 20 * 2; rect.size.width += 20 * 2; //将点转换到与响应事件的区域在同一个坐标系内 CGPoint p = [self convertPoint:point toView:self.superview]; //判断点是否在新的事件响应区域内 if (CGRectContainsPoint(rect, p)) { return self; } else { return [super hitTest:point withEvent:event]; } }