Странное поведение UISwipeGestureRecognizer - приложения для микрозамерзания

У меня странная проблема с Swiperecognizer.

У меня есть объекты на экране.

let SpawnObject = SKAction.run({
        () in

        showobject()

    })

    let delay1 = SKAction.wait(forDuration: 0.9)
    let SpawnDelay1 = SKAction.sequence([SpawnObject,delay1])
    let SpawnDelayForever1 = SKAction.repeatForever(SpawnDelay1)
    self.run(SpawnDelayForever1)

    let distance = CGFloat(self.frame.height + 200)
    let moveObject = SKAction.moveBy(x: -distance, y: 0, duration: TimeInterval(0.004 * distance))
    let removeObject = SKAction.removeFromParent()
    moveAndRemove = SKAction.sequence([moveObject,removeObject])

У меня есть объект с некоторой физикой (Object2, B.png похож).

func showObject(){
    let texture =  SKTexture(imageNamed: "A.png")
    object = SKSpriteNode(texture: texture)
    object.name = "A"
    object.position = CGPoint(x: 0, y: self.frame.width)
    object.setScale(0.7)
    object.zPosition = 2
    object.run(moveAndRemove)

    object.physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
    object.physicsBody?.categoryBitMask = PhysicsCategory.Object
    object.physicsBody?.collisionBitMask = PhysicsCategory.Object2
    object.physicsBody?.contactTestBitMask = PhysicsCategory.Object2
    object.physicsBody?.affectedByGravity = false
    object.physicsBody?.isDynamic = true


    addChild(object)
}

Я установил распознавание пролистывания в штрихах

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        location = touch.location(in: self)
        node = self.atPoint(location)
        if node.name == "A" {
            //node.run(SKAction.moveBy(x: 1000, y: 0, duration: 1)).  //Here I try set action only to touch
            let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(rightSlide(_:)))
            rightSwipe.direction = .right
            view!.addGestureRecognizer(rightSwipe)
        }
        else if node.name == "B" {
            //node.run(SKAction.moveBy(x: -1000, y: 0, duration: 1)).   //Here I try set action only to touch
            let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(leftSlide(_:)))
            leftSwipe.direction = .left
            view!.addGestureRecognizer(leftSwipe)
        }else {print ("Blank space")}
    }

}

func leftSlide(_ sender: UISwipeGestureRecognizer){
    if node.name == "B" {
    node.run(SKAction.moveBy(x: -1000, y: 0, duration: 1))
    }else {print ("Bad swipe")}
    }
func rightSlide(_ sender: UISwipeGestureRecognizer){
    if node.name == "A" {
    node.run(SKAction.moveBy(x: 1000, y: 0, duration: 1))
    }else {print ("Bad swipe")}
}

А теперь проблема. Объекты показываются на экране, когда я их провожу, они исчезают в стороне. Все работает нормально, пока я не проведу что-то около 50 объектов, после чего каждое следующее приложение замораживания смахивает на микросекунды, объекты странно перепрыгивают на несколько пикселей вниз (больше ударов, больше пикселей) и возвращаются в исходное положение, а после этого странного поведения объект смахивает прочь, Больше ударов = больше заморозки и больше прыжков.

Я пытаюсь отключить физику и ничего. Но когда я изменяю действие непосредственно на прикосновение (не нужно проводить пальцем, просто коснитесь), приложение работает нормально всегда. Поэтому должен быть неправильный распознаватель пролистывания. Или нет? Я проверяю CPU и MEMORY и CPU имеет 35%, а память составляет около 50 МБ. Узлов на экране максимум 20. FPS 60, но когда приложение зависает, оно снижается до 58 (как мерцание).

Любое предложение? Как диагностировать, где проблема? Спасибо!

1 ответ

Решение

Вместо добавления распознавателя каждый раз в методе touchesBegan, вы должны сделать следующее:

1) Создайте массив для хранения всех распознавателей, чтобы вы могли легко удалить их позже

2) Добавьте распознаватели только один раз. Обратите внимание, что распознаватели добавляются в представление, а не в сцену

3) Удалить их, когда сцена собирается удалить из вида

import SpriteKit

class GameScene: SKScene,SKPhysicsContactDelegate {


     var recognizers:[UIGestureRecognizer] = []

    override func didMove(to view: SKView) {


        let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(GameScene.leftSlide(recognizer:)))
        leftSwipe.direction = .left
        leftSwipe.numberOfTouchesRequired = 1
        self.view?.addGestureRecognizer(leftSwipe)
        recognizers.append(leftSwipe)

         //do the same for other recognizers

    }

    func leftSlide(recognizer:UISwipeGestureRecognizer){
        print("Swipe")
    }

//define other methods here to handle other recognizers...

  override func willMove(from view: SKView) {
    super.willMove(from: view)

    for recognizer in recognizers {
        self.view?.removeGestureRecognizer(recognizer)
    }
    recognizers.removeAll()
}
}
Другие вопросы по тегам