Événements tactiles et mouvements dans Xamarin.iOS
Il est important de comprendre les événements tactiles et les API tactiles dans une application iOS, car ils sont au cœur de toutes les interactions physiques avec l’appareil. Toutes les interactions tactiles impliquent un UITouch
objet. Dans cet article, nous allons apprendre à utiliser la UITouch
classe et ses API pour prendre en charge l’interaction tactile. Plus tard, nous développerons nos connaissances pour apprendre à prendre en charge les mouvements.
Activation de l’interaction tactile
Les contrôles dans UIKit
( ceux qui sont sous-classés à partir d’UIControl ) dépendent tellement de l’interaction utilisateur qu’ils ont des mouvements intégrés à UIKit et qu’il n’est donc pas nécessaire d’activer l’interaction tactile. Il est déjà activé.
Toutefois, la plupart des vues dans UIKit
n’ont pas d’interaction tactile activée par défaut. Il existe deux façons d’activer l’interaction tactile sur un contrôle. La première méthode consiste à case activée la case Interaction utilisateur activée dans le panneau propriétés de l’Designer iOS, comme illustré dans la capture d’écran suivante :
Nous pouvons également utiliser un contrôleur pour définir la UserInteractionEnabled
propriété sur true sur une UIView
classe. Cela est obligatoire si l’interface utilisateur est créée dans le code.
La ligne de code suivante est un exemple :
imgTouchMe.UserInteractionEnabled = true;
Événements tactiles
Il existe trois phases d’interaction tactile qui se produisent lorsque l’utilisateur touche l’écran, déplace son doigt ou retire son doigt. Ces méthodes sont définies dans UIResponder
, qui est la classe de base pour UIView. iOS remplace les méthodes associées sur et UIView
pour gérer l’interaction UIViewController
tactile :
TouchesBegan
: cette opération est appelée lorsque l’écran est touché pour la première fois.TouchesMoved
: elle est appelée lorsque l’emplacement de l’interaction tactile change lorsque l’utilisateur fait glisser ses doigts autour de l’écran.TouchesEnded
ouTouchesCancelled
–TouchesEnded
est appelé lorsque les doigts de l’utilisateur sont levés de l’écran.TouchesCancelled
est appelé si iOS annule l’interaction tactile, par exemple, si un utilisateur déplace son doigt d’un bouton pour annuler une pression.
Les événements tactiles se déplacent de manière récursive dans la pile des UIViews, pour case activée si l’événement tactile se trouve dans les limites d’un objet de vue. Il s’agit souvent de tests de positionnement. Elles sont d’abord appelées en haut ou en haut UIView
, UIViewController
puis sont appelées sur et UIView
UIViewControllers
en dessous dans la hiérarchie de la vue.
Un UITouch
objet est créé chaque fois que l’utilisateur touche l’écran. L’objet UITouch
inclut des données sur l’interaction tactile, telles que le moment où l’interaction tactile s’est produite, l’endroit où elle s’est produite, si l’interaction tactile a été un mouvement de balayage, etc. Les événements tactiles obtiennent une propriété touches , qui NSSet
contient une ou plusieurs touches. Nous pouvons utiliser cette propriété pour obtenir une référence à une interaction tactile et déterminer la réponse de l’application.
Les classes qui remplacent l’un des événements tactiles doivent d’abord appeler l’implémentation de base, puis obtenir l’objet UITouch
associé à l’événement. Pour obtenir une référence à la première interaction tactile, appelez la propriété et castez-la AnyObject
en tant que UITouch
comme indiqué dans l’exemple suivant :
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
UITouch touch = touches.AnyObject as UITouch;
if (touch != null)
{
//code here to handle touch
}
}
iOS reconnaît automatiquement les touches rapides successives à l’écran et les collecte toutes en un seul appui dans un seul UITouch
objet. Cela facilite la vérification d’un double appui que la vérification de la TapCount
propriété, comme illustré dans le code suivant :
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
UITouch touch = touches.AnyObject as UITouch;
if (touch != null)
{
if (touch.TapCount == 2)
{
// do something with the double touch.
}
}
}
Multi-touch
L’interaction tactile multiple n’est pas activée par défaut sur les contrôles. Le multi touch peut être activé dans le Designer iOS, comme illustré par la capture d’écran suivante :
Il est également possible de définir l’interaction tactile par programmation en définissant la MultipleTouchEnabled
propriété comme indiqué dans la ligne de code suivante :
imgTouchMe.MultipleTouchEnabled = true;
Pour déterminer le nombre de doigts qui ont touché l’écran, utilisez la Count
propriété sur la UITouch
propriété :
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
lblNumberOfFingers.Text = "Number of fingers: " + touches.Count.ToString();
}
Détermination de l’emplacement tactile
La méthode UITouch.LocationInView
retourne un objet CGPoint qui contient les coordonnées de l’interaction tactile dans une vue donnée. En outre, nous pouvons tester pour voir si cet emplacement se trouve dans un contrôle en appelant la méthode Frame.Contains
. L’extrait de code suivant en montre un exemple :
if (this.imgTouchMe.Frame.Contains (touch.LocationInView (this.View)))
{
// the touch event happened inside the UIView imgTouchMe.
}
Maintenant que nous avons une compréhension des événements tactiles dans iOS, nous allons en savoir plus sur les modules de reconnaissance de mouvement.
Modules de reconnaissance de mouvement
Les modules de reconnaissance de mouvement peuvent considérablement simplifier et réduire l’effort de programmation pour prendre en charge l’interaction tactile dans une application. Les modules de reconnaissance de mouvement iOS regroupent une série d’événements tactiles en un seul événement tactile.
Xamarin.iOS fournit la classe UIGestureRecognizer
en tant que classe de base pour les modules de reconnaissance de mouvement intégrés suivants :
- UITapGestureRecognizer : pour un ou plusieurs appuis.
- UIPinchGestureRecognizer : pincement et écartement des doigts.
- UIPanGestureRecognizer : mouvement panoramique ou glissement.
- UISwipeGestureRecognizer : balayage dans n’importe quelle direction.
- UIRotationGestureRecognizer : rotation de deux doigts dans le sens des aiguilles d’une montre ou dans le sens inverse des aiguilles d’une montre.
- UILongPressGestureRecognizer : appuyez longuement, parfois appelé appui long ou clic long.
Le modèle de base pour utiliser un module de reconnaissance de mouvement est le suivant :
- Instancier le module de reconnaissance de mouvement : tout d’abord, instanciez une
UIGestureRecognizer
sous-classe. L’objet instancié est associé à une vue et est récupéré par la mémoire lorsque la vue est supprimée. Il n’est pas nécessaire de créer cette vue en tant que variable de niveau classe. - Configurer les paramètres de mouvement : l’étape suivante consiste à configurer le module de reconnaissance de mouvement. Consultez la documentation de Xamarin sur
UIGestureRecognizer
et ses sous-classes pour obtenir la liste des propriétés qui peuvent être définies pour contrôler le comportement d’unUIGestureRecognizer
instance. - Configurer la cible : en raison de son Objective-C héritage, Xamarin.iOS ne déclenche pas d’événements lorsqu’un module de reconnaissance de mouvement correspond à un mouvement.
UIGestureRecognizer
a une méthode –AddTarget
qui peut accepter un délégué anonyme ou un Objective-C sélecteur avec le code à exécuter lorsque le module de reconnaissance de mouvement établit une correspondance. - Activer le module de reconnaissance de mouvement : tout comme avec les événements tactiles, les mouvements ne sont reconnus que si les interactions tactiles sont activées.
- Ajouter le module de reconnaissance de mouvement à la vue : la dernière étape consiste à ajouter le mouvement à une vue en appelant
View.AddGestureRecognizer
et en lui transmettant un objet de reconnaissance de mouvement.
Pour plus d’informations sur la façon de les implémenter dans le code, consultez les exemples de reconnaissance de mouvement.
Lorsque la cible du mouvement est appelée, une référence au mouvement qui s’est produit lui est transmise. Cela permet à la cible de mouvement d’obtenir des informations sur le mouvement qui s’est produit. L’étendue des informations disponibles dépend du type de module de reconnaissance de mouvement utilisé. Pour plus d’informations sur les données disponibles pour chaque UIGestureRecognizer
sous-classe, consultez la documentation de Xamarin.
Il est important de se rappeler qu’une fois qu’un module de reconnaissance de mouvement a été ajouté à une vue, la vue (et toutes les vues situées en dessous) ne reçoivent aucun événement tactile. Pour autoriser les événements tactiles simultanément avec les mouvements, la CancelsTouchesInView
propriété doit avoir la valeur false, comme illustré par le code suivant :
_tapGesture.Recognizer.CancelsTouchesInView = false;
Chacun UIGestureRecognizer
a une propriété State qui fournit des informations importantes sur la status du module de reconnaissance de mouvement. Chaque fois que la valeur de cette propriété change, iOS appelle la méthode d’abonnement pour lui donner une mise à jour. Si un module de reconnaissance de mouvements personnalisé ne met jamais à jour la propriété State, l’abonné n’est jamais appelé, ce qui rend le module de reconnaissance de mouvement inutile.
Les mouvements peuvent être résumés comme l’un des deux types suivants :
- Discret : ces mouvements ne se déclenchent que la première fois qu’ils sont reconnus.
- Continu : ces mouvements continuent de se déclencher tant qu’ils sont reconnus.
Les modules de reconnaissance de mouvement existent dans l’un des états suivants :
- Possible : il s’agit de l’état initial de tous les modules de reconnaissance de mouvement. Il s’agit de la valeur par défaut de la propriété State.
- Commencé : lorsqu’un mouvement continu est reconnu pour la première fois, l’état est défini sur Commencé. Cela permet aux abonnés de faire la différence entre le moment où la reconnaissance de mouvement démarre et le moment où elle est modifiée.
- Modifié : une fois qu’un mouvement continu a commencé, mais n’est pas terminé, l’état est défini sur Modifié chaque fois qu’une touche se déplace ou change, tant qu’elle est toujours dans les paramètres attendus du mouvement.
- Annulé : cet état est défini si le module de reconnaissance est passé de Commencé à Modifié, puis que les touches ont changé de manière à ne plus s’adapter au modèle du mouvement.
- Reconnu : l’état est défini lorsque le module de reconnaissance de mouvement correspond à un ensemble de touches et informe l’abonné que le mouvement est terminé.
- Terminé : il s’agit d’un alias pour l’état Reconnu.
- Échec : lorsque le module de reconnaissance de mouvements ne peut plus correspondre aux touches qu’il écoute, l’état passe à Échec.
Xamarin.iOS représente ces valeurs dans l’énumération UIGestureRecognizerState
.
Utilisation de plusieurs mouvements
Par défaut, iOS n’autorise pas les mouvements par défaut à s’exécuter simultanément. Au lieu de cela, chaque module de reconnaissance de mouvement recevra des événements tactiles dans un ordre non déterministe. L’extrait de code suivant illustre comment exécuter simultanément un module de reconnaissance de mouvement :
gesture.ShouldRecognizeSimultaneously += (UIGestureRecognizer r) => { return true; };
Il est également possible de désactiver un mouvement dans iOS. Il existe deux propriétés déléguées qui permettent à un module de reconnaissance de mouvement d’examiner l’état d’une application et les événements tactiles actuels, afin de prendre des décisions sur la façon dont et si un mouvement doit être reconnu. Les deux événements sont les suivants :
- ShouldReceiveTouch : ce délégué est appelé juste avant que le module de reconnaissance de mouvement ne soit passé à un événement tactile, et permet d’examiner les touches et de déterminer quelles touches seront gérées par le module de reconnaissance de mouvement.
- ShouldBegin : elle est appelée lorsqu’un module de reconnaissance tente de changer l’état de Possible à un autre état. Le retour de false force l’état du module de reconnaissance de mouvement à passer à Échec.
Vous pouvez remplacer ces méthodes par un fort typé UIGestureRecognizerDelegate
, un délégué faible ou une liaison via la syntaxe du gestionnaire d’événements, comme illustré par l’extrait de code suivant :
gesture.ShouldReceiveTouch += (UIGestureRecognizer r, UITouch t) => { return true; };
Enfin, il est possible de mettre en file d’attente un outil de reconnaissance de mouvements afin qu’il réussisse uniquement si un autre outil de reconnaissance de mouvement échoue. Par exemple, un outil de reconnaissance de mouvements en appuyant sur un seul appui ne doit réussir que lorsqu’un dispositif de reconnaissance de mouvement double appui échoue. L’extrait de code suivant fournit un exemple de ceci :
singleTapGesture.RequireGestureRecognizerToFail(doubleTapGesture);
Création d’un mouvement personnalisé
Bien qu’iOS fournisse certains modules de reconnaissance de mouvements par défaut, il peut être nécessaire de créer des modules de reconnaissance de mouvements personnalisés dans certains cas. La création d’un outil de reconnaissance de mouvements personnalisé implique les étapes suivantes :
- Sous-classe
UIGestureRecognizer
. - Remplacez les méthodes d’événement tactile appropriées.
- Status de reconnaissance en bulles via la propriété State de la classe de base.
Un exemple pratique de cela sera abordé dans la procédure pas à pas Utilisation de Touch dans iOS .