美文网首页Swift开发
子控件超出父控件响应点击事件

子控件超出父控件响应点击事件

作者: KOLee | 来源:发表于2019-09-30 13:46 被阅读0次
// 作用: 去寻找点击的View
// 点击调用: 当一个事件传递给当前View,就会调用.
// 返回值: 返回的是谁,谁就是最适合的View(就会调用最适合的View的touch方法)
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        return super.hitTest(point, with: event)
}

hitTest的底层实现:

  • 先看自己是否能接受触摸事件

  • 再看触摸点是否在自己身上

  • 从后往前遍历子控件,拿到子控件后,再次重复1,2步骤,要把父控件上的坐标点转换为子控件坐标系下的点,再次执行hitTest方法

  • 若是最后还没有找到合适的view,那么就return self,自己就是合适的view

应用实例(tabbar中间凸出按钮可以优雅的实现):

extension UITabBar {
    
    open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if (!self.isUserInteractionEnabled || self.isHidden || self.alpha <= 0.01)
        {
            return nil
        }
        if (self.point(inside: point, with: event)) { //判断点击位置,如果是自己想点击的位置就将触摸事件传给自己
            return hhl_hitTest(point: point, event: event!)
        }else {
            let tabBarItemWidth = ScreenW/CGFloat(self.items!.count) // 获取每个tabbarItem的宽度
            
            let left = self.center.x - tabBarItemWidth/2;
            let right = self.center.x + tabBarItemWidth/2;
            
            if (point.x < right &&
                point.x > left)
            {   //当点击的point的x坐标是中间item范围内,才去修正落点
                let otherPoint = CGPoint(x: point.x, y: point.y + 20) // 20为高出父视图的高度
                return self.hhl_hitTest(point: otherPoint, event: event!)
            }
        }
        return nil
    }
    
    /// 返回点击子视图位置的view
    fileprivate func hhl_hitTest(point: CGPoint, event: UIEvent) -> UIView? {

        for subView in self.subviews {
            let convertedPoint = subView.convert(point, from: self)
            let hitView = subView.hitTest(convertedPoint, with: event)
            if (hitView != nil) {
                return hitView
            }
        }
        
        return nil

    }
}

最后在中间tabBarItem添加一个扇形的对应图片即可

相关文章

网友评论

    本文标题:子控件超出父控件响应点击事件

    本文链接:https://www.haomeiwen.com/subject/bovcpctx.html