借助“响应链”解决实际问题

文章介绍了如何通过重写UIButton的pointInside方法扩大其响应区域,以及自定义UIView的hitTest方法处理子视图超出父视图的情况,使得即使点击位置不在控件中心也能响应点击事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景一:增加图片按钮的响应区域

自定义按钮继承自UIButton,重写pointInside来扩大控件的响应区域。

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    // 按钮中心点坐标
    float centerX = self.bounds.size.width / 2;
    float centerY = self.bounds.size.height / 2;

    // 点击位置坐标
    float pointX = point.x;
    float pointY = point.y;

    // 分别获取点击位置坐标X、Y与按钮中心坐标距离
    float dltX = fabsf(pointX - centerX);
    float dltY = fabsf(pointY - centerY);

    float width = self.frame.size.width;
    float height = self.frame.size.height;
    
    //在控件大小基础上,四周扩大10像素,来增加响应区域
    return dltX<=width/2 + 10 &&dltY<=height/2 + 10;
}

这样即使点击区域不在按钮上面,但是距离按钮边缘没有超过10像素,按钮仍然会认为当前碰触的屏幕坐标是在按钮控件当中,因此按钮可以成为此次操作的响应者来响应点击事件,这样就可以实现增大热区的效果。

场景二:若子视图超出父视图,超出部分也可以成为响应者

自定义UIView,重写hitTest方法

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (self.clipsToBounds || self.hidden || (self.alpha <= 0.01)) {
        return nil;
    }
    UIView *result = [super hitTest:point withEvent:event];
    if (result) {
        return result;
    }
    for (UIView *subview in self.subviews) {
        CGPoint subPoint = [subview convertPoint:point fromView:self];
        result = [subview hitTest:subPoint withEvent:event];
        if (result) {
            return result;
        }
    }
    return nil;
}

当父视图不能成为响应者时,遍历视图所有的子视图,若子视图可以成为响应者,则返回该子视图成为响应者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值