之前面试的时候,面试官问事件传递得的流程,就提到了一个问题,怎么重写一个基于UIView的触摸范围,当时没认真想过,举个例子,怎么扩大button的点击范围,之前只是加一个透明的button,覆盖,扩大点击范围。
现在有个需求,button 设置layer后,其实可视的区域小了,但是单击区域还是原来的矩形 CGRect,怎么让其点击区域仅限于圆内呢,就在于重写
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event,事件一层层传递,之后由hitTest 决定哪个view来捕捉,
针对Layer圆形区域
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = nil;
BOOL pointInRound =[self touchPointInsideCircle:self.center targetPoint:point];
if (pointInRound) {
hitView = self;
}else
{
hitView = nil;
}
return hitView;
}
-(BOOL)touchPointInsideCircle:(CGPoint)center targetPoint:(CGPoint)point
{
CGFloat dist = sqrtf((point.x - center.x) * (point.x - center.x) +
(point.y - center.y) * (point.y - center.y));
return (dist <= self.layer.cornerRadius);
重写button的hitTest方法,即可限制button的点击区域。
}
两种方法扩大button的点击区域
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
{
CGRect bounds = self.bounds;
//若原热区小于44x44,则放大热区,否则保持原大小不变
CGFloat widthDelta = MAX(150.0 - bounds.size.width, 0);
CGFloat heightDelta = MAX(150.0 - bounds.size.height, 0);
bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);
return CGRectContainsPoint(bounds, point);
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGRect rectBig = CGRectInset(self.bounds, -(10.0/2), -(10.0/2));
if (CGRectContainsPoint(rectBig, point)) {
return self;
}else{
return nil;
}
return self;
}
//判断点在哪个里面
CGRectContainsPoint(leftBtn.frame, point)