美文网首页
事件穿透

事件穿透

作者: leejnull | 来源:发表于2020-03-11 13:33 被阅读0次

    事件响应和传递这篇文章中,讲了iOS中的事件响应和传递,今天在做项目的时候,正好碰到了一个应用的场景,因此记录下来。

    需求

    首页头部需要添加这样一个视图


    image.png

    点击左右两个按钮,底部的滑块跟着滑动,同时也可以拖动滑块到选中的按钮位置。

    思路和问题

    看到这个设计图一开始的想法就是,左右两个按钮,底部一个滑块视图,然后到做的时候,发现如果要做手势拖拽的话,那么由于层级关系,滑块肯定是在两个按钮下面的,如果要触发滑动手势,势必会被按钮的点击事件阻止。


    image.png

    通过重写hitTest方法解决

    首先判断点击点是位于左侧按钮区域还是右侧按钮区域,在根据按钮的选中状态来判断。
    初始状态时左侧按钮选中,右侧没选中,同时滑块位于左侧。
    如果触摸点在右侧按钮区域,此时应该走的流程是响应右侧按钮事件。
    如果触摸点在左侧区域,此时左侧区域是选中状态,应该响应的是滑块的拖动事件。
    依照这个思路,就有了下面的这段代码

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let superHitPoint = self.convert(point, to: self.superview)
        if superHitPoint.x <= self.frame.width {
            if self.frame.minX > 0 {    // 点击左侧按钮,但是现在响应的是右侧按钮,原样传递上去
                return super.hitTest(point, with: event)
            }
            if self.isSelected {
                return strikeView
            } else {
                return super.hitTest(point, with: event)
            }
        } else {
            if self.frame.minX == 0 {     // 同理
                return super.hitTest(point, with: event)
            }
            if self.isSelected {
                return strikeView
            } else {
                return super.hitTest(point, with: event)
            }
        }
    }
    

    这里要注意的一点是,由于事件响应链是系统会从后往前遍历子视图,我们点击任何一个区域,两个按钮都会响应hitTest方法,在判断触摸点的区域之后,还要判断一下当期响应的按钮是不是我们期望的按钮,如果不是,则不作任何改动。

    相关文章

      网友评论

          本文标题:事件穿透

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