Comment passer des touches de UIView à UIScrollView


4

similaires à this thread et bien d'autres, j'ai un contrôleur de vue avec un fichier NIB qui a cette mise en page ...

  • a. UIView (480 x 320) - stocke une image d'arrière-plan
  • b. UIScrollView (480 x 220) - Est un sélecteur de niveau scrollview
  • c. UIView (480 x 320) - contient un graphique animé de premier plan

Les trois éléments ci-dessus sont des sous-vues de la vue principale de la NIB. UIView (c) correspond à la taille de l'écran de l'iPhone et au sommet de la hiérarchie. Sur celui-ci, j'ai placé un personnage qui s'anime en fonction de la position tactile actuelle dans cette vue. Cependant, le problème est que, avec cette vue recevant des touches, je ne peux pas obtenir les touches à la ScrollView (b) ci-dessous. J'ai encore besoin d'utiliser les touches en (c), mais aussi besoin de passer des touches pertinentes/glissements à l'UIScrollView ci-dessous.

Quelqu'un peut-il conseiller comment cela peut-il être fait? J'ai lu divers articles sur l'utilisation de hittest mais je ne veux pas compenser complètement les touches, j'ai juste besoin de les transférer après pour que le scrollview fonctionne toujours normalement.

Merci,

1

Si elle était moi, je mettrais le ScrollView en tant que délégué de la vue de dessus. Ceci, bien sûr, nécessiterait que la vue de dessus est un sublcass personnalisé de UIView, de sorte que vous pouvez définir

id delegate; 

et

@property (nonatomic, assign) id delegate; 

dans le fichier d'en-tête. Vous pouvez ensuite régler le ScrollView en tant que délégué à quelque chose le long des lignes de

[topView setDelegate:scrollView]; 

Avec cela en place, vous pouvez envoyer des messages (dans votre cas, toucher des événements) à la ScrollView quand ils sont nécessaires. Si, par exemple, vous voulez envoyer tous les événements touchBegan, vous auriez ceci:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self.delegate touchesBegan:touches withEvent:event]; 
} 

Bien sûr, si vous ne voulez que certains événements passés, vous mis en place dans les méthodes vos paramètres dire quand appeler [self.delegate ....] ou [super ....]. Ce dernier effectuera l'action pour la vue plutôt que dans le scrollView. J'espère que cela aide

  0

Le problème avec ceci, c'est que les balayages ne sont pas détectés dans le scrollview - j'ai essayé cette méthode plus tôt avant d'arriver à l'état dans lequel je suis maintenant. lol ... et c'est un état! Cependant vous m'avez fait penser à passer l'information nécessaire pour animer, mais sans les événements tactiles. Je vais regarder dans cela! 20 sept.. 112011-09-20 17:24:38

  0

Haha, je sais que je me sens trop bien. Mais je suis content que cela vous a amené à penser à de nouvelles façons d'aborder le problème. C'est généralement mon défaut pour des problèmes comme ça. Fondamentalement, il suffit de définir les conditions dans lesquelles envoyer des événements au délégué et aller à partir de là, que ce soit des gestes ou des touches ou autre chose. Si vous avez besoin de plus de contrôle, vous pouvez sous-classer le scrollView et adopter un protocole personnalisé à partir de la vue de dessus qui spécifie les méthodes à appeler et comment les implémenter. J'espère que ce n'est pas déroutant, mais si c'est quelque chose que vous pourriez vouloir essayer, je serais plus qu'heureux d'aider 20 sept.. 112011-09-20 17:30:12

  0

Ouais, c'est certainement un problème de conception - je sais toujours quand je fais quelque chose d'une manière stupide parce que ça ressemble à une mauvaise programmation! Appréciez vos suggestions cependant. 20 sept.. 112011-09-20 17:36:14

  0

Pas de problème. Je suis toujours heureux d'aider. J'espère que tout sera réglé bientôt. 20 sept.. 112011-09-20 17:45:46

  0

Essayez d'ajouter ceci: [super touchesBegan: touche withEvent: event]; Sachez également que si vous surchargez l'une des méthodes de gestion des touches, vous devez remplacer les quatre touches: touchesBegan, touchesMoved, touchesEnded AND touchesCancelled. 02 oct.. 132013-10-02 08:13:11


-1

Sous UIScrollVeiw et passer outre la touchesShouldCancelInContentView: méthode comme ceci:

-(BOOL)touchesShouldCancelInContentView:(UIView *)view 
{ 

    if ([view isKindOfClass:[UIButton class]]) {//or whatever class you want to override 
     return YES; 
    } 

    if ([view isKindOfClass:[UIControl class]]) { 
     return NO; 
    } 

    return YES; 
} 
  0

pourquoi downvote pour cela? 13 sept.. 132013-09-13 11:47:10

  0

Probablement parce que la vue C n'est pas une sous-vue de la scrollview, et ne sera donc pas incluse dans le test 'touchesShouldCancelInContentView'. (Je suppose que c'est pourquoi quelqu'un vous a voté) 28 mars. 142014-03-28 02:29:09


1

est ici une des solutions plus simples qui ont bien fonctionné pour moi:

En vue C (la vue de premier plan qui est au-dessus UIScrollView), faites la largeur et la hauteur à la fois 0 (de sorte que la vue ne soit plus techniquement au dessus de la scrollview) et définissez ClipsToBounds = NO (de sorte que le contenu de la vue C apparaisse toujours en haut de la scrollview). Cela a fonctionné comme un charme pour moi.

self.viewC.clipsToBounds = NO; 
CGRect frame = self.viewC.frame; 
self.viewC.frame = CGRectMake(frame.origin.x, frame.origin.y, 0, 0); 

Notez que si la vue C contient des contrôles interactifs, ils ne fonctionneront plus.

  0

Très intelligent. M'a aidé avec quelque chose. 08 janv.. 142014-01-08 15:28:43

  0

Si l'origine est 0, vous pouvez utiliser CGRectZero à la place, beaucoup plus propre. 16 oct.. 142014-10-16 11:50:59

  0

Vous ne pouviez pas simplement définir .userInteractionEnabled à NO/false à la place? 29 sept.. 162016-09-29 01:24:22