Swift - UIPanGestureRecognizer, выбирающий все слои, когда требуется только верхний слой - PullRequest
1 голос
/ 06 марта 2019

У меня есть функция, которая создает линию перетаскивания, чтобы соединить 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
    }
  }
}

Примечание: некоторые строки кодов взяты из пользовательских расширений. Я держал их, потому что они говорят сами за себя.

Спасибо за помощь

Ответы [ 2 ]

1 голос
/ 06 марта 2019

Есть способ погулять.Похоже, вы просто хотите, чтобы ваш жест оказался на одну кнопку выше всех остальных, добавив, таким образом, переменную вне цикла и каждый раз, когда нажимали кнопку, по сравнению с переменной ее уровня в точке z.

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 голосов
/ 06 марта 2019

A UIView имеет свойство, называемое subViews, где элементы с более высокими индексами находятся перед элементами с более низкими индексами.Например, subView с индексом 1 находится перед subView с индексом 0.

При этом, чтобы получить кнопку сверху, вы должны отсортировать buttonArray таким же образом subViews свойство UIView организовано.Предполагая, что все ваши кнопки - это братья и сестры одного и того же UIView (это может быть не всегда так, но вы можете настроить их так, чтобы они правильно сортировались):

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

Таким образом, сохраняя ваш buttonArray отсортировано таким образом, вы хотите кнопку, которая содержит let point = sender.location(in: button) с более высоким индексом в массиве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...