Comment voler des touches de UIScrollView?

Aujourd'hui sur mon temps, j'ai fait une recherche approfondie sur la façon de voler touche à partir d'un UIScrollView et de les envoyer instantanément à une sous-vue, tout en conservant le comportement par défaut pour le reste de défilement de la vue. Envisager d'avoir un UIPickerView à l'intérieur d'un UITableView. Le comportement par défaut, c'est que si vous faites glisser votre doigt sur le sélecteur de vue, le défilement de la vue de défilement et le sélecteur de vue reste inchangé.

La première chose que j'ai essayé était pour remplacer

- (BOOL)touchesShouldCancelInContentView:(UIView *)view

et permet tout simplement pas le UIScrollView pour annuler touche à l'intérieur du sélecteur de vue. Cela fonctionne, mais il a un effet de bord désagréable. Vous souhaitez que le sélecteur de vue de répondre immédiatement, et ainsi vous aurez à définir delaysContentTouches PAS. Le problème est que vous ne voulez pas le reste de l'affichage de la table de répondre immédiatement, parce que si c'est la vue de la table de cellules obtiendrez toujours mis en évidence pour quelques millisecondes avant que le défilement commence.

La deuxième chose que j'ai essayé était pour remplacer

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

parce que j'avais lu que le défilement de l'affichage retourne toujours lui-même, afin de "voler" les touches de son sous-vues et de les envoyer plus tard à la sous-vue s'ils n'étaient pas d'intérêt pour le défilement de l'affichage. Cependant, ce n'est pas vrai. UIScrollView par défaut de mise en œuvre de la méthode hitTest:withEvent: renvoie en fait la sous-vue qui doit recevoir le toucher. Au lieu de cela, il utilise des modules de reconnaissance de geste pour intercepter la touche.

Donc la troisième chose que j'ai essayé était de mettre en place mon propre geste de reconnaissance et de l'amener à l'échec si le contact était en dehors de la vue du sélecteur et sinon réussir. Puis j'ai mis tous le défilement de la vue du geste modules de reconnaissance à l'échec à moins que mon geste de reconnaissance échoué en utilisant le code suivant:

for (UIGestureRecognizer * gestureRecognizer in self.tableView.gestureRecognizers)
{
    [gestureRecognizer requireGestureRecognizerToFail:myRecognizer];
}

Cela ne fait voler la touche de défilement de la vue, mais le sélecteur de vue ne reçoit jamais d'eux. Donc j'ai pensé que je pourrais peut-être juste envoyer toutes les touches que mon geste de reconnaissance reçoit l'aide de ce code:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches)
        [touch.view touchesBegan:touches withEvent:event];
}

Le code ci-dessus est une version simplifiée. J'ai aussi assurez-vous que la vue est une vue de sélecteur (ou un de ses sous-vues) et de définir l'état approprié pour le geste de reconnaissance comme je l'ai mentionné ci-dessus. J'ai également fait de même pour annulé, clos et déplacé. Cependant, le sélecteur de vue était toujours pas de réponse.

J'ai aussi essayé une dernière chose avant de retourner à mon travail régulier. Au cours de mes nombreuses recherches sur google, j'ai lu que imbriquée UIScrollViews tout comme par magie travaillé depuis 3.x, donc j'ai essayé de mettre mon sélecteur de vue à l'intérieur d'un imbriquée UIScrollView et définissez les propriétés suivantes: le

scrollView.delaysContentTouches = NO;
scrollView.canCancelContentTouches = NO;

Que l'on pourrait s'attendre à l'extérieur de défilement de la vue n'a pas de traiter l'intérieur de défilement de la vue tout différent de ce qu'il a traité le sélecteur de vue, de sorte que l'intérieur de défilement de la vue n'a pas reçu de la touche. J'ai pensé que c'était un long shot, mais c'était assez simple à mettre en œuvre, alors j'ai pensé que cela valait la peine de donner un coup de feu.

Ce que je sais, c'est que UIScrollView a un geste de reconnaissance nommé UIScrollViewDelayedTouchesBeganGestureRecognizer qui intercepte les touches et les envoie à la appropriée sous-vue après 150 (?) ms. Je pense que je devrais être capable d'écrire un analogue de reconnaissance qui provoque le défilement de la vue par défaut des modules de reconnaissance à l'échec et au lieu de retarder la touche envoie immédiatement à la vue de sélecteur. Donc si quelqu'un sait comment écrire une telle reconnaissance s'il vous plaît laissez-moi savoir et si vous avez une autre solution pour le problème, vous êtes les bienvenus partager ainsi.

Vous remercie pour la lecture par le biais de l'ensemble de la question et même si vous ne connaissez pas la réponse, vous pouvez toujours upvote la question, de sorte qu'il devient de plus en plus l'attention (espérons-le de quelqu'un qui peut répondre). Merci! 🙂

InformationsquelleAutor Erik B | 2011-01-07