Почему Xcode TouchesEnded () topMost затронул узел всегда возвращает дочерние узлы, а не родительский узел? - PullRequest
0 голосов
/ 31 марта 2019

У меня есть Subclassed SKSpriteNode в качестве кнопки меню ()

MenuButton () содержит 2 детей:

  • SKSpriteNode (изображение)

  • SKSpriteNode (немного текста)

Когда запускается нижеприведенное, если пользователь касается части кнопки, содержащей изображение или текст (дочерние элементы MenuButton ()), он не выполняется, поскольку изображение / текст имеют другое имя для кнопки и они первые touchedNode.

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        guard let touch = touches.first else { return }
        let location = touch.location(in: self)
        let touchedNode = atPoint(location)
        let touchedNodeName = atPoint(location).name

        if let nodeName = touchedNodeName, nodeName == ("btnPlay") { self.showGameModeMenu() }
}

Ранее я использовал:

let touchedNodes = nodes(at: location)
for node in nodes {
    if let nodeName = node.name, nodeName == "btnPlay" { self.showGameModeMenu() }
}

Однако, когда другой узел (btnCloseLeaderboard) представлен поверх btnPlay, он проходит по циклу и выполняет оба, а не только самый верхний узел (btnCloseLeaderboard)

Я попытался установить isUserInteractionEnabled = false для дочерних узлов, но это не работает. Тогда он все еще рассматривается как самый верхний узел.

Как мне предотвратить это?

1 Ответ

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

Звучит так, будто вы хотите показать игровое меню, если имя родительского дочернего элемента - «btnPlay» или если сам узел с именем «btnPlay» коснулся (для касаний вне изображения или текстовых дочерних элементов).Если это так, вы можете изменить свой верхний код на это:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    let location = touch.location(in: self)
    let touchedNode = atPoint(location)
    if touchedNode.parent?.name == "btnPlay" || touchedNode.name == "btnPlay" { showGameModeMenu() }
}
...