2016-04-14 7 views
1

J'essaye de créer une sous-classe de UIControl et de toucher des pistes pour changer l'apparence du contrôle. Je ne sais pas pourquoi mais si j'ajoute l'action (pour .TouchUpInside) de IB ou du code, quand je touche le contrôle la méthode d'action de registre est appelée deux fois.
La trace de la pile me dit que le premier appel vient de _sendActionsForEvents:withEvent:, le second n'est pas clair.
Ici comment je méthodes de piste: OPPOSER
UIControl personnalisé, action appelée deux fois

override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
     let touchPoint = touch.locationInView(self) 
     if CGRectContainsPoint(bounds, touchPoint) { 
      sendActionsForControlEvents(.TouchDragInside) 
     } 
     else { 
      sendActionsForControlEvents(.TouchDragOutside) 
     } 
     return true 
    } 


override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
    sendActionsForControlEvents(.TouchDown) 
    return true 
} 

override func endTrackingWithTouch(touch: UITouch?, withEvent event: UIEvent?) { 
    guard let tou = touch else { return } 
    let touchPoint = tou.locationInView(self) 
    if CGRectContainsPoint(bounds, touchPoint) { 
     sendActionsForControlEvents(.TouchUpInside) 
    } 
    else { 
     sendActionsForControlEvents(.TouchUpOutside) 
    } 
} 

override func cancelTrackingWithEvent(event: UIEvent?) { 
    sendActionsForControlEvents(.TouchCancel) 
} 

J'ai trouvé aussi ce answer mais il ne semble pas correspondre à mon problème, parce que quand j'ajoute la cible pour l'événement .TouchUpInside I don N'obtenez aucune action automatiquement du répartiteur d'événements comme indiqué dans cette réponse.

+0

Avez-vous mis des points d'arrêt sur chacun des sendActionsForControlEvents et voir si plus de 1 est touché? Recevez-vous un événement tiré une fois pour le TouchDown et une fois pour le TouchUpInside? – fsb

+0

Bien sûr, je suppose que j'ai trouvé la réponse. Je posterai plus tard. Fondamentalement, il semble que les actions sont déjà envoyées par superclasse, mais je veux traquer si tous les événements ou seulement quelques-uns. Donc j'envoie quelque chose qui est déjà envoyé – Andrea

Répondre

1

J'ai trouvé que j'avais mal compris la documentation, et probablement beaucoup de personnes (voir quelques exemples sur internet).
Le remplacement des méthodes mentionnées ne vous permet pas de gérer la répartition des événements. Pour cela, il est probablement préférable d'utiliser sendAction:to:forEvent:.
Ces considérations viennent après avoir fait un petit projet avec une sous-classe UIControl et ajouter quelques actions pour les événements de contrôle les plus populaires:

  • monotouche
  • toucher à l'intérieur
  • toucher à l'extérieur
  • glisser à l'extérieur
  • glisser à l'intérieur
  • valeur modifiée

RÉSULTATS
À l'exception de la valeur changé, tous les autres événements sont déjà appelés, les méthodes de suivi sont même surchargés. Si nous voulons envoyer une valeur changée, nous devons l'appeler nous-mêmes, et cela a du sens parce que, comme son nom l'indique, il n'est pas lié à des contacts.
Une chose que j'ai trouvé intéressante est quand le suivi à l'extérieur est appelé, il semble être appelé lorsque l'utilisateur traîne le doigt environ 50% de plus en dehors des limites du contrôle, je m'attendais juste après avoir dépassé ses limites

class TestControl: UIControl { 
    override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
     let touchPoint = touch.locationInView(self) 
     print(touchPoint) 
     return true 
    } 
    override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
     let touchPoint = touch.locationInView(self) 
     print(touchPoint) 

     return true 
    } 

    override func endTrackingWithTouch(touch: UITouch?, withEvent event: UIEvent?) { 
     guard let touch = touch else { return } 
     let touchPoint = touch.locationInView(self) 
     print(touchPoint) 

    } 
} 

class ViewController: UIViewController { 

    @IBOutlet weak var tezst: TestControl! 


    @IBAction func touchDown(sender: AnyObject){ 
     print("Touch Down") 
    } 
    @IBAction func touchUpInside(sender: AnyObject){ 
     print("Touch up inside") 
    } 

    @IBAction func touchUpOutside(sender: AnyObject){ 
     print("Touch up outside") 
    } 
    @IBAction func touchDragOutside(sender: AnyObject){ 
     print("Touch drag outside") 
    } 
    @IBAction func touchDragInside(sender: AnyObject){ 
     print("Touch drag inside") 
    } 
    @IBAction func valueChanged(sender: AnyObject){ 
     print("Value changed") 
    } 
}