Passer le mouvement de défilement vertical vers UITableView ci-dessous

(édité pour plus de clarté)

J'ai un UITableView. En plus de cela est un UIView avec un geste Pan attaché. Ce panoramique balaie vers la gauche et la droite pour changer la table sous-jacente. J'utilise la méthode d'action du geste de panoramique pour déplacer la table. Cela fonctionne bien.

Cependant, l'UIView et son geste Pan interfèrent avec le défilement haut / bas de UITableView. Comment puis-je envoyer le défilement haut / bas vers la table et garder la gauche-droite sur la zone de la vue?

--------------------------------------- | | | ---------------------- | | | | | | | | | | | | | | UITableView | | | | | UIView | | | | + | | | | PanGesture | | | | | | | | | | | | | | | | | | | ---------------------- | | | | | --------------------------------------- 

La méthode déclenchée par le geste Pan est comme ceci

  -(void)move:(UIPanGestureRecognizer*)sender { CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view]; float xTest = fabsf(translatedPoint.x); float yTest = fabsf(translatedPoint.y); if ( xTest>yTest) { // Move table view left-right.. this works } else { // Send up-down scrolling gesture to table view????? How to? } } 

Je viens de résoudre un problème similaire, sauf pour les casseroles verticales au lieu des horizontales. Je ne suis pas sûr à 100% de votre cas d'utilisation, donc ce n'est peut-être pas ce que vous cherchez, mais cela peut vous mener dans la bonne direction.

J'ai sous-classé UIPanGestureRecognizer, et mis en œuvre la méthode touchesMoved, et vérifié pour voir si le geste avait une plus grande modification horizontale ou verticale. Voici un extrait. Le crédit appartient à un message stackoverflow différent, mais je ne trouve pas le lien pour le moment. (Désolé d'avance pour le mauvais formatting, première publication)

 -(void)touchesMoved:(NSSet*) touches withEvent:(UIEvent *)event { [super touchesMoved:touches withEvent:event]; if(self.state == UIGestureRecognizerStateFailed) return; CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; CGPoint prevPoint = [[touches anyObject] previousLocationInView:self.view]; moveX += prevPoint.x - currentPoint.x; moveY += prevPoint.y - currentPoint.y; if(!drag) { if(abs(moveY) > abs(moveX)) drag = YES; else self.state = UIGestureRecognizerStateFailed; } } -(void)reset { [super reset]; drag = NO; moveX = 0; moveY = 0; } 

Dans mon controller de vue parent, que je crois être le UITableView dans ce cas, j'ai également mis en œuvre ce qui suit. Je pense que dans votre cas, vous voudriez returnner non si c'est un panoramique horizontal.

 -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if([gestureRecognizer isKindOfClass:[VerticalPanGestureRecognizer class]]) { return YES; } return NO; } 

Faites-moi savoir si cela n'est pas clair.

Bonne chance!

UIGestureRecognizer a une propriété qui empêche les gestes reconnus de transmettre leurs events à la vue-hierachy – les sons comme si c'était la bonne option pour vous. Essayez cela et placez-le sur NO sur vos reconnaisseurs de gestes en question.

cancelsTouchesInView

Valeur booleanne affectant la remise des touches à une vue lorsqu'un mouvement est reconnu.

 @property(nonatomic) BOOL cancelsTouchesInView 

Discussion

Lorsque cette propriété est définie sur YES (valeur par défaut) et que le récepteur reconnaît son geste, les touches en attente de ce geste ne sont pas envoyées à la vue et les touches précédentes sont annulées via un message touchesCancelled: withEvent: envoyé à la vue. Si un détecteur de mouvement ne reconnaît pas son geste ou si la valeur de cette propriété est NON, la vue reçoit toutes les touches de la séquence multi-touch.

Disponible dans iOS 3.2 et versions ultérieures.

De la reference UIGestureRecognizer .

OK, la réponse a été d'append le panoramique à l'UITableView au lieu de l'UIView. Je vérifie pour voir si l'location du geste est dans les limites de l'UIView (maintenant caché dans le xib), comme ceci:

  - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer { CGPoint translation = [gestureRecognizer locationInView:self.view]; CGRect frame = self.slideTarget.frame; if (CGRectContainsPoint(frame, translation)) { return YES; } else { return NO; } } 

Boom.

Je comprends que vous voulez que le geste dans UIView soit géré selon sa direction (vertical -> scroll table, horizontal -> scroll UIView). J'ai lu -did pas essayé- à ce sujet: Le UISwipeGestureRecognizer a une direction d'atsortingbut – à partir de la docs:

 The permitted direction of the swipe for this gesture recognizer. 

Peut-être que cela peut vous aider?

EDIT: Oh, eh bien, je ne savais pas que vous regardiez un UIPanRecognizer (trop "glisser" là) … Peut-être que vous pouvez passer le geste à la table lorsque la direction de la panoramique est "assez verticale", comme indiqué par translationInView: ..?

Dans la méthode de votre geste Pan, écrivez ceci:

 - (void)pan:(UIPanGestureRecognizer *)gesture { CGPoint translatedPoint = [gesture translationInView:self.tableView]; if (ABS(translatedPoint.y) > 10.0f) { self.tableView.bounds = CGRectMake(0, -translatedPoint.y, 320, 460); } if (ABS(translatedPoint.x) > 10.0f) { // swipe left/right code... } } 

Ici vous imitez le défilement de votre vue de table en changeant sa propriété de limites. Mais ce code ne fera pas rebondir la vue de table. Cet effet peut être obtenu en sauvegardant l'état de la propriété de rebond au début du mouvement de panoramique, puis en affectant cette propriété lorsque le mouvement se termine.

Comme je peux avoir un sens de votre exigence que vous devez faire défiler la table lorsque vous interagissez avec une autre vue. Donc, voir les couches sera comme:

UINavigationController -> view (Le controller de navigation aura UITableViewController) UITableViewController (Il aura UiTableView)

Et à la fin

UIView (sous-vue UINavigationController.view UIView)

Donc, vous voulez que si vous faites un panoramique (défilement) sur votre UIView, alors votre TableView défilera correctement.

Vous devez donc créer une class de votre UIView (Supposons CustomView). Ensuite, implémentez les methods suivantes dans votre class CustomView.

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *hitView = [super hitTest:point withEvent:event]; // If the hitView is THIS view, return the view that you want to receive the touch instead: if (hitView == self) { return _tableView; } else if ([hitView isKindOfClass:[UIButton class]]) { return hitView; } return _tableView; } 

Si vous avez une sous-vue de button sur votre CustomView également. Ensuite, vous obtiendrez une sélection sur elle aussi.

Pardonnez-moi pour ma mauvaise explication mais je viens de find cette solution pour mon problème et je veux le partager avec vous.

Faites-moi savoir si vous avez besoin de plus d'explications. Je vais expliquer plus tard.

Implémentez la méthode UIGestureReconizerDelegate , nommée - gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:

Il renvoie false par défaut, l'implémente et renvoie true.

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return true; } 

Et, n'oubliez pas de définir la propriété delegate du geste.

 // Set the delegate of the panGesture. For example self.panGestureReconizer.delegate = ... // 

D'Apple doc

(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

Demande au délégué si deux reconnaisseurs de gestes doivent être autorisés à reconnaître des gestes simultanément.

Valeur de return

OUI pour autoriser à la fois gestureRecognizer et otherGestureRecognizer à reconnaître leurs gestes simultanément. L'implémentation par défaut renvoie NO: aucun deux gestes ne peuvent être reconnus simultanément.

Discussion

Cette méthode est appelée lorsque la reconnaissance d'un geste par gestureRecognizer ou autreGestureRecognizer empêche l'autre reconnaissance de gestes de reconnaître son geste. Notez que le return de YES est garanti pour permettre une reconnaissance simultanée; le return de NO, d'autre part, n'est pas garanti pour empêcher la reconnaissance simultanée parce que le délégué de l'autre reconnaissance de geste peut returnner OUI.


Lire la suite