web-dev-qa-db-fra.com

Xcode & Swift - Détection de la touche utilisateur d'UIView dans UIScrollView

Je crée un jeu, similaire à Flappy Bird, mais l'utilisateur tient son doigt sur l'écran et évite les obstacles, plutôt que de taper pour faire voler l'oiseau.

Je fais cela en ayant un UIScrollView, dans lequel les UIView sont utilisés comme obstacles. Lorsque l'utilisateur touche une UIView, le jeu est terminé.

Comment puis-je détecter les utilisateurs toucher une UIView à partir d'un UIScrollView? J'utilise Swift avec Xcode Beta 4.

EDIT: Ceci est une capture d'écran du jeu

This is screenshot of the game

Comme vous pouvez le voir, l'utilisateur déplace son doigt entre les blocs gris (UIViews) en faisant défiler vers le haut.

26
user2397282

En définissant userInteractionEnabled sur NO pour votre vue de défilement, le contrôleur de vue commencera à recevoir des événements tactiles puisque UIViewController est une sous-classe de UIResponder. Vous pouvez remplacer une ou plusieurs de ces méthodes dans votre contrôleur de vue pour répondre à ces touches:

  • touchesBegan: withEvent:
  • touchMoved: withEvent:
  • touchesEnded: withEvent:
  • touchCancelled: withEvent:

J'ai créé un exemple de code pour montrer comment vous pouvez le faire:

class ViewController: UIViewController {
    @IBOutlet weak var scrollView: UIScrollView!

    // This array keeps track of all obstacle views
    var obstacleViews : [UIView] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create an obstacle view and add it to the scroll view for testing purposes
        let obstacleView = UIView(frame: CGRectMake(100,100,100,100))
        obstacleView.backgroundColor = UIColor.redColor()
        scrollView.addSubview(obstacleView)

        // Add the obstacle view to the array
        obstacleViews += obstacleView
    }

    override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
        testTouches(touches)
    }

    override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
        testTouches(touches)
    }

    func testTouches(touches: NSSet!) {
        // Get the first touch and its location in this view controller's view coordinate system
        let touch = touches.allObjects[0] as UITouch
        let touchLocation = touch.locationInView(self.view)

        for obstacleView in obstacleViews {
            // Convert the location of the obstacle view to this view controller's view coordinate system
            let obstacleViewFrame = self.view.convertRect(obstacleView.frame, fromView: obstacleView.superview)

            // Check if the touch is inside the obstacle view
            if CGRectContainsPoint(obstacleViewFrame, touchLocation) {
                println("Game over!")
            }
        }
    }

}
50
s1m0n

Vous pouvez ajouter par programme un identificateur de mouvement comme suit

var touch = UITapGestureRecognizer(target:self, action:"action")
scrollView.addGestureRecognizer(touch)

Cependant, cet identificateur de gestes ne fonctionnera pas pour vous. UITapGestureRecognizer ne reviendra que pour un tap, pas un tap et maintenez, et UILongPressGestureRecognizer ne donne pas d'informations sur l'emplacement, donc vous voulez utiliser un UIPanGestureRecognizer. Il vous indique continuellement jusqu'où le toucher s'est déplacé.

var touch = UIPanGestureRecognizer(target:self, action:"handlePan")
scrollView.addGestureRecognizer(touch)

@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    let translation = recognizer.translationInView(self.view)
    recognizer.setTranslation(CGPointZero, inView: self.view)
}

Vous pouvez utiliser la constante "translation" pour déplacer votre objet, elle représente la distance à laquelle la personne a glissé son doigt. Utilisez cela plus l'emplacement de votre oiseau pour déplacer l'oiseau vers un nouveau point. Vous devez remettre la traduction à zéro après avoir appelé cette fonction.

Edit: Avec le format de votre jeu, ce code devrait être la meilleure méthode.

Donc, tous ensemble, le code pour trouver l'emplacement de votre doigt doit être le suivant.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    for touch: AnyObject in touches {
        let location = touch.locationInView(yourScrollView)
    }
}


@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    let translation = recognizer.translationInView(self.view)
    var currentLocation : CGPoint = CGPointMake(location.x+translation.x, location.y+translation.y)
    recognizer.setTranslation(CGPointZero, inView: self.view)
}

currentLocation est un CGPoint contenant l'emplacement de la touche actuelle, partout où le doigt est glissé. Comme je ne sais pas comment vous créez les vues à éviter, vous devrez utiliser la coordonnée y de currentLocation pour déterminer les limites x des vues à éviter à ce y et utiliser des comparateurs <ou> pour déterminer si la frontière x du toucher se trouve à l'intérieur de l'une de ces vues.

Remarque: vous devez déclarer l'emplacement afin qu'il soit accessible dans handlePan

var location : CGPoint = CGPointZero
15
trumpeter201