iOS 超出父视图不响应点击事件的解决方法

本文介绍如何通过重写hitTest方法使UIButton即使超出其父视图范围也能响应点击事件。通过获取点击位置并转换为相对于子视图的坐标,判断该坐标是否在子视图范围内来决定是否触发点击事件。

默认情况下,如果一个UIButton超出了它的父视图,那么超出父视图的部分,是不响应点击事件的,当需要超出父视图依然相应点击事件的时候,就需要重写UIView的

func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView?

方法。此方法中的point是在接受点击的view(即父视图)坐标体系中的坐标,会递归调用:

public func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool

方法,因此,我们需要得到这个point相对于子视图(以UIButton为例)的坐标点,可以用:

public func convertPoint(point: CGPoint, fromView view: UIView?) -> CGPoint

这个方法获得,
有了这个点,就可以判断这个点是否在子视图的范围内,并相应事件,举例如下:

class TestView:UIView {

    var testBtn:UIButton!

    override init(frame: CGRect) {
        super.init(frame: frame);

        testBtn = UIButton(type: UIButtonType.Custom);
        testBtn.frame = CGRectMake(-50, -50, 50, 50);
        testBtn.backgroundColor = UIColor.blueColor();
        testBtn.addTarget(self, action: #selector(testBtnClicked), forControlEvents: UIControlEvents.TouchUpInside);
        self.addSubview(testBtn);
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {

        // 得到不处理的情况下,相应点击的view结果,目的是不影响其它的点击
        let result = super.hitTest(point, withEvent: event);

        // 得到点相对于button的坐标
        let testBtnPoint = self.testBtn.convertPoint(point, fromView: self);
        // 如果坐标在button内,返回这个button,就会相应button的事件
        if (self.testBtn.pointInside(testBtnPoint, withEvent: event)) {
            return self.testBtn;
        }

        // 返回super的响应点击的view
        return result;
    }



    func testBtnClicked() {
        print("btn clicked");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值