UITapGestureRecognizer déclencher par programmation d'un robinet de mon point de vue
Edit: mis à Jour pour rendre la question plus évident
Edit 2: en Fait la question plus précise à mon problème réel. Je suis actuellement à la recherche de prendre des mesures si elles appuyez n'importe où SAUF dans un texte à l'écran-champ. Donc, je ne peux pas simplement écouter les événements à l'intérieur de la zone de texte, j'ai besoin de savoir si ils taraudés n'importe où dans la Vue.
Je suis en train d'écrire des tests unitaires pour affirmer qu'une certaine action est prise lorsqu'un geste de reconnaissance reconnaît un robinet dans certaines coordonnées de mon point de vue. Je veux savoir si je peux créer par programmation d'une touche (à des coordonnées spécifiques) qui seront traitées par le UITapGestureRecognizer. Je suis d'essayer de simuler l'interaction de l'utilisateur lors d'un test unitaire.
La UITapGestureRecognizer est configuré dans l'Interface Builder
//MYUIViewControllerSubclass.m
-(IBAction)viewTapped:(UITapGestureRecognizer*)gesture {
CGPoint tapPoint = [gesture locationInView:self.view];
if (!CGRectContainsPoint(self.textField, tapPoint)) {
//Do stuff if they tapped anywhere outside the text field
}
}
//MYUIViewControllerSubclassTests.m
//What I'm trying to accomplish in my unit test:
-(void)testThatTappingInNoteworthyAreaTriggersStuff {
//Create fake gesture recognizer and ViewController
MYUIViewControllerSubclass *vc = [[MYUIViewControllersSubclass alloc] init];
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer initWithView: vc.view];
//What I want to do:
[[ Simulate A Tap anywhere outside vc.textField ]]
[[ Assert that "Stuff" occured ]]
}
mise à jour de question
va scotcher sur un point de vue spécifique ou un bouton serait suffisant?
Le geste de reconnaissance qui est de reconnaître les robinets sur l'ensemble de la vue, et ensuite déterminer si oui ou non le robinet s'est produite à l'intérieur d'un champ de texte -- cependant, je veux prendre des mesures si elles appuyez sur l'EXTÉRIEUR de ce champ, afin de n'écouter que pour les robinets qui textfield irait à l'encontre du but. Je devrais probablement avoir fait cette distinction dans la question.
Mise à jour une question de faire cette distinction. J'ai d'abord exclus parce que je ne voulais pas avoir un trop long post -- mais vous avez raison, c'est une distinction importante à faire.
OriginalL'auteur Matt H. | 2012-12-30
Vous devez vous connecter pour publier un commentaire.
Je pense que vous avez plusieurs options ici:
Peut être le plus simple serait d'envoyer un
push event action
à votre point de vue mais je ne pense pas que ce que vous voulez vraiment puisque vous voulez être en mesure de choisir l'endroit où le robinet d'action se produit.Vous pouvez utiliser
UI automation tool
qui est fourni avec XCode instruments. Cette blog explique bien comment faire pour automatiser vos tests de l'INTERFACE utilisateur avec le script.Il y a cette solution trop qui expliquent comment synthétiser les événements tactiles sur l'iPhone, mais assurez-vous que vous utilisez uniquement celles pour les tests unitaires. Ceci ressemble plus à un hack pour moi et je vais envisager cette solution en dernier recours si les deux points précédents ne pas répondre à votre besoin.
L'Option 1 n'est pas valide. "sendActionsForControlEvents" ne fonctionne que pour UIControl objets; pas UIView.
OriginalL'auteur tiguero
Ce que vous essayez de faire est très difficile (mais pas totalement impossible) tout en restant sur l' (iTunes)chemin d'accès.
Permettez-moi d'abord le projet de la droit;
La bonne voie pour le faire, c'est à l'aide de UIAutomation. UIAutomation fait exactement ce que vous demandez, il simule le comportement de l'utilisateur pour toutes sortes de tests.
Maintenant que dure;
La question que vos problèmes se résume à instancier un nouveau UIEvent. (Onu)heureusement UIKit n'offre pas les constructeurs de tels événements dus à des raisons évidentes de sécurité. Il existe cependant des solutions qui ont fonctionné dans le passé, vous ne savez pas si ils le font encore.
Regarder Matt Galagher est génial blog de la rédaction d'un solution sur la façon de synthétiser les événements tactiles.
OriginalL'auteur Till
Si utilisé dans les tests, vous pouvez utiliser une bibliothèque de test appelé SpecTools qui contribue à tout cela et plus, ou utiliser directement le code:
À la fois, à la bibliothèque ainsi que l'extrait de l'utilisation privée de l'API et sera probablement entraîner un rejet si elle est utilisée à l'extérieur de votre suite de tests ...
OriginalL'auteur Ondrej
J'ai été confrontée au même problème, en essayant de simuler un clic sur une cellule de tableau pour automatiser un test pour une-vue-contrôleur qui gère tapant sur une table.
Le contrôleur dispose d'une salle de UITapGestureRecognizer créé comme ci-dessous:
Le test unitaire doit simuler une touche de sorte que le gestureRecognizer pourrait déclencher l'action telle qu'elle provenait de l'interaction de l'utilisateur.
Aucune des solutions proposées travaillé dans ce scénario, j'ai donc résolu de décoration UITapGestureRecognizer, de truquer les méthodes exactes appelé par le contrôleur. J'ai donc ajouté un "performTap la méthode de l'appel à l'action d'une façon que le contrôleur lui-même n'est pas au courant de l'endroit où l'action est originaire de. De cette façon, je pourrais faire une unité de test pour le contrôleur indépendant de la geste de reconnaissance, juste de l'action déclenchée.
C'est ma catégorie, j'espère que ça aide quelqu'un.
OriginalL'auteur Glauco Aquino
Ok, j'ai tourné la ci-dessus dans une catégorie qui fonctionne.
Bits intéressants:
init
méthode contient d'importantes configuration de la logique; on pouvait deviner ce qui est prévu (nombre de prises, le nombre de touches, quoi d'autre?Le fichier d'en-tête est triviale; voici la mise en œuvre.
Elle me bat. Essayez-le! Mais tout ce que vous devez faire dans l'application, vous devriez être en mesure de faire sans cette couche supplémentaire de truquer les choses.
N'est ce encore aujourd'hui ? J'ai essayé ceci mais pas de réponse
OriginalL'auteur tooluser
devrait être
parce que le cgpoint doit être récupéré à partir exactement où le geste de la cible, plutôt que d'essayer de deviner d'où la vue c'est dans
OriginalL'auteur kevinl
Réponse par @Ondrej mis à jour à Swift 4:
Utilisation:
OriginalL'auteur Vlad