Swift - 当只想选择顶层时,UIPanGestureRecognizer选择所有图层

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

我有一个功能,它创建一个拖动线来连接2个按钮。这工作正常,但如果某些按钮相互重叠,如果我拖动它们重叠的位置,它将选择两者。我只想连接顶部按钮。

enter image description here

我认为问题在于sender.location选择顶部和底部的图层。有没有办法告诉sender.location只选择顶视图?感谢您的任何输入和指导

func addPanReconiser(view: UIView){

    let pan = UIPanGestureRecognizer(target: self, action: #selector(DesignViewController.panGestureCalled(_:)))
    view.addGestureRecognizer(pan)
}

@objc func panGestureCalled(_ sender: UIPanGestureRecognizer) {

    let currentPanPoint = sender.location(in: self.view)

    switch sender.state {
    case .began:

        panGestureStartPoint = currentPanPoint
        self.view.layer.addSublayer(lineShape)

    case .changed:
        let linePath = UIBezierPath()
        linePath.move(to: panGestureStartPoint)
        linePath.addLine(to: currentPanPoint)

        lineShape.path = linePath.cgPath
        lineShape.path = CGPath.barbell(from: panGestureStartPoint, to: currentPanPoint, barThickness: 2.0, bellRadius: 6.0)

        for button in buttonArray {
            let point = sender.location(in: button)

            if button.layer.contains(point) {
                button.layer.borderWidth = 4
                button.layer.borderColor = UIColor.blue.cgColor
            } else {
                button.layer.borderWidth = 0
                button.layer.borderColor = UIColor.clear.cgColor
            }
        }

    case .ended:

        for button in buttonArray {
            let point = sender.location(in: button)

            if button.layer.contains(point){

                //DO my Action here
                lineShape.path = nil
                lineShape.removeFromSuperlayer()

            }
        }
    default: break
    }
  }
}

注意:某些代码行来自自定义扩展。我把它们留在了,因为它们是自我解释的。

谢谢您的帮助

swift xcode uiview uipangesturerecognizer uiview-hierarchy
2个回答
1
投票

有办法四处走走。看起来你只是希望你的手势最终在一个按钮上方,所以通过在循环外添加一个var并且每次选择一个按钮,与z中它的级别的var相比较。

case .ended:
        var pickedButton: UIButton?
        for button in buttonArray {
            let point = sender.location(in: button)

            if button.layer.contains(point){
                if pickedButton == nil {
                    pickedButton = button
                } else {
                    if let parent = button.superView, parent.subviews.firstIndex(of: button) > parent.subviews.firstIndex(of: pickedButton!) {
                        pickedButton = button
                    }
                }
            }
        }
        //DO my Action with pickedButton here
        lineShape.path = nil
        lineShape.removeFromSuperlayer()

0
投票

UIView有一个名为subViews的属性,其中索引较高的元素位于索引较低的元素前面。例如,索引1处的subView位于subView前面,索引为0。

话虽如此,要获得顶部的按钮,你应该按照buttonArraysubViews属性组织你的UIView排序。假设你的按钮都是同一个UIView的兄弟姐妹(这可能不一定是这种情况,但你可以调整它们以便正确排序):

var buttonArray = view.subviews.compactMap { $0 as? UIButton }

因此,保持你的buttonArray按这种方式排序,你想要的按钮是包含阵列中具有更高索引的let point = sender.location(in: button)的按钮。

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