iOS曲线视图有轻击问题

问题描述 投票:1回答:1

我需要创建一个合并了顶视图和底视图的视图,其中顶视图的底部需要有一条曲线,而顶视图和底视图都需要在点击时执行不同的操作。我能够如下创建此视图

enter image description here

这是我的故事板约束的屏幕截图

enter image description here

这是我的曲线视图类

class CurveView: UIView {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        self.createBottomCurve()
    }

    private func createBottomCurve() {
        let offset: CGFloat = self.frame.width / 1.2
        let bounds: CGRect = self.bounds
        let rectBounds: CGRect = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.size.width, height: bounds.size.height / 2)
        let rectPath: UIBezierPath = UIBezierPath(rect: rectBounds)
        let ovalBounds: CGRect = CGRect(x: bounds.origin.x - offset / 2, y: bounds.origin.y, width: bounds.size.width + offset, height: bounds.size.height)
        let ovalPath: UIBezierPath = UIBezierPath(ovalIn: ovalBounds)
        rectPath.append(ovalPath)
        let maskLayer: CAShapeLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = rectPath.cgPath
        self.layer.mask = maskLayer
    }
}

这是viewcontroller类中的实现

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    @IBOutlet weak var greenCurveView: CurveView!
    @IBOutlet weak var yellowView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let greenViewTap = UITapGestureRecognizer(target: self, action: #selector(handleGreenViewTap(_:)))
        greenViewTap.delegate = self
        greenCurveView.addGestureRecognizer(greenViewTap)
        let yellowViewTap = UITapGestureRecognizer(target: self, action: #selector(handleYellowTap(_:)))
        yellowViewTap.delegate = self
        yellowView.addGestureRecognizer(yellowViewTap)
    }

    @objc func handleGreenViewTap(_ pan: UITapGestureRecognizer ){
        print("Green View is tapped")
    }

    @objc func handleYellowTap(_ pan: UITapGestureRecognizer ){
        print("Yellow View is tapped")
    }

}

这很好,除了在下图中红色点击突出显示的矩形区域中的黄色视图的情况下。在下图中,如果单击矩形中的黄色区域,则会获得绿色视图的水龙头,这是有意义的,因为黄色视图位于绿色视图之后。那么,如何确定该区域的黄色区域?任何帮助表示赞赏

enter image description here

ios swift uigesturerecognizer xcode11 bezier
1个回答
0
投票

您需要指示CurveView可以在哪里窃听,在这种情况下,应在其自己的路径内:

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
       return rectPath.contains(point)
}

所以您的CurveView总体上看起来像这样:

class CurveView: UIView {

    var rectPath = UIBezierPath()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        self.createBottomCurve()
    }

    private func createBottomCurve() {
        let offset: CGFloat = self.frame.width / 1.2
        let bounds: CGRect = self.bounds
        let rectBounds: CGRect = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.size.width, height: bounds.size.height / 2)
        rectPath = UIBezierPath(rect: rectBounds)
        let ovalBounds: CGRect = CGRect(x: bounds.origin.x - offset / 2, y: bounds.origin.y, width: bounds.size.width + offset, height: bounds.size.height)
        let ovalPath: UIBezierPath = UIBezierPath(ovalIn: ovalBounds)
        rectPath.append(ovalPath)
        let maskLayer: CAShapeLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = rectPath.cgPath
        self.layer.mask = maskLayer
    }

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
           return rectPath.contains(point)
    }
}

输出:

© www.soinside.com 2019 - 2024. All rights reserved.