6
votes

Détecter des balayages horizontaux dans un Uiscrollview avec un rouleau vertical

J'ai un Uiscrollview qui est d'environ 600 pixels en hauteur et 320 de largeur. Donc, je permet à l'utilisateur de faire défiler verticalement.

J'essaie également de capturer des échappements horizontales à la vue. Le problème semble être que lorsqu'un utilisateur passe horizontalement avec un mouvement vertical accidentel, les défilements UiscrollView et ma méthode de déléguée touchée ne sont jamais appelées. p>

Voici mon code: P>

- (void)touchesEnded: (NSSet *)touches withEvent: (UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint currentPosition = [touch locationInView:self];

    if (currentPosition.x + 35 < gestureStartPoint.x)
    {  
        NSLog(@"Right");
    }    
    else if (currentPosition.x - 35 > gestureStartPoint.x)
    {
        NSLog(@"Left");
    }    
    else if (!self.dragging)
    {
        [self.nextResponder touchesEnded: touches withEvent:event]; 
    }

    [super touchesEnded: touches withEvent: event];
}


0 commentaires

3 Réponses :


5
votes

Uiscrollview essaie de comprendre qui touche à son contenu et qui défilent, en fonction du mouvement immédiatement après le début d'une touche. Fondamentalement, si le contact semble être un défilement tout de suite, il gère ce geste et le contenu ne le voit jamais; Sinon, le geste est passé (avec un très court retard pour la première touche).

Dans mon expérience, j'ai été capable de capturer des échappements horizontales dans le contenu d'un Uiscrollview qui manipulait le défilement vertical uniquement - il vient de travailler par défaut pour moi. Je l'ai fait en définissant le contenu pour être identique à la largeur de la trame , qui correspond suffisamment d'informations pour indiquer au uiscrollview que Il ne traitera pas de défilement horizontal.

On dirait que vous avez des problèmes avec le comportement par défaut, cependant. Un quincaillerie GOTCHA est qu'il est très difficile de simuler un coup de doigt sur le pavé de chenouillage d'un ordinateur portable. Si j'étais vous, je testerais la configuration par défaut UiscrollView à l'aide d'une souris ou de préférence, sur l'appareil lui-même. J'ai constaté que ces méthodes d'entrée fonctionnent beaucoup mieux pour transporter des balayeurs.

Si cela ne fonctionne pas, voici un paragraphe très pertinent d'Apple UISCrollView DOCS:

Parce qu'une vue de défilement n'a pas de barres de défilement, il doit savoir si une touche signale une intention de faire défiler versus une intention de suivre une sous-évaluation dans le contenu. Pour faire cette détermination, cela intercepte temporairement un événement de retouche en démarrant une minuterie et, avant que la minuterie incendie, en voyant si le doigt touchant fait un mouvement. Si le temps tire sans changement significatif de position, la vue de défilement envoie des événements de suivi dans la sous-assisté touchée de la vue de contenu. Si l'utilisateur glisse alors suffisamment de doigt avant que la minuterie ne s'éloigne, la vue de défilement annule tout suivi dans la sous-vision et effectue le défilement lui-même. Les sous-classes peuvent remplacer le TouchESShouldbegin: sans contrainte: incontentview: , Pagingenabled et TouchESShouldCancelincincontentView: méthodes (appelées par la vue de défilement) pour affecter la manière dont La vue de défilement gère les gestes de défilement.

En résumé, vous pouvez essayer ce qu'ils suggèrent par sous-classement uiscrollview et remplaçant les méthodes suggérées.


1 commentaires

Tyler, merci pour la réponse. Je peux détecter les "balayages" horizontal, mais seulement s'ils ont très peu de changements dans Y. Si j'ai déplacé plus de + -5 pixels à peu près sur l'axe des Y, il semble que le ScrollView prend la revue et commence à défiler verticalement. Ce n'est pas si réaliste que cela me prend quelques essais (sur l'appareil) pour obtenir un balayage avec ce petit changement sur l'axe des Y. Avez-vous ressenti un comportement similaire?



1
votes

Si la méthode de @ Tyler ne fonctionne pas, essayez de mettre une vue juste sur l'Uiscrollview et de gérer toutes les balayeurs horizontales dans la touche ToucheBegan de cette vue et passez à la verticale au prochain répondeur. Vous pouvez être un peu flou et gérer tout ce qui a plus d'un mouvement horizontal que vertical comme balayage horizontal et transmettez les balayages verticaux plus purs sur l'UISCrollView (via Nextreesponder).


1 commentaires

La nouvelle vue est celle qui ne reçoit aucune touche? Est-ce un enfant de la ScrollView, ou un frère de frère, au-dessus de cela? Est-il défini pour accepter l'interaction utilisateur?



0
votes

Swift 4 Solution forte>

Enregistrer deux reconnaissants de geste dans la vue ViewDiDload () dans votre contrôleur d'affichage p>

class MyViewController: UIViewController, UIGestureRecognizerDelegate

...

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                       shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}


0 commentaires