2010-12-07 8 views
1

que je dois faire quelque chose comme ceci:UIScrollView avec UIImageView comme subviews, taping UIImageView

UIScrollView avec UIImageViews que ses sous-vues. Lorsque l'utilisateur appuie sur UIImageViews, une action se produit. Mais quand l'utilisateur veut faire défiler UIScrollView devrait défiler même si le défilement a commencé à UIImageView (à l'endroit où UIImage de UIImageView est affiché).

Basiquement je peux obtenir un des deux scénarios:

  1. je peux obtenir que si l'utilisateur tape sur UIImageView (qui est sous-vue UIScrollView) une action se produit, mais quand vous essayez de faire défiler par draging doigt UIImageView l'action se produit également (et je veux qu'un défilement se produise).

  2. Je peux faire ce quiles lorsque l'utilisateur appuie sur la vue va défiler, mais si l'utilisateur appuie sur UIImageView l'action ne se produira pas.

Je ne peux pas vous faire tout de mon code, car je teste beaucoup de aprroches ici et là et il est peu en désordre il ne servirait à rien du tout (sans tonnes de commentaires).

Existe-t-il une solution propre et simple pour cela?

Ok voici un code:

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


if(isDragging == NO) 
{ 


    return [super hitTest:point withEvent:event]; 
} 
NSLog(@"dragging ><><><><><>>><><><><>"); 
     return nil; 

} 

Maintenant, si je retourne nul alors je peux faire défiler, mais je ne peux pas exploiter mon UIImageView pour une action. Si je retourne [super hitTest: point withEvent: event] je ne peux pas faire défiler mon UIIMageView. IsDragging est un code de test permettant de déterminer si j'essaie de faire défiler ou simplement de tapoter sur. Mais le test d'occurrence se produit avant que je puisse définir la propriété isDragging en fonction de l'événement en cours.

Voici mon initialisation

-(id) initWithCoder:(NSCoder *)aDecoder 
{ 

if(self = [super initWithCoder:aDecoder]) 
{ 
    [self setUserInteractionEnabled:YES]; 
    UISwipeGestureRecognizer *swipeRecLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)]; 
    swipeRecLeft.direction = UISwipeGestureRecognizerDirectionDown; 

    UISwipeGestureRecognizer *swipeRecRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)]; 
    swipeRecRight.direction = UISwipeGestureRecognizerDirectionUp; 

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapSingle)];  

    [self addGestureRecognizer:swipeRecRight]; 
    [self addGestureRecognizer:swipeRecLeft]; 
    [self addGestureRecognizer:singleTap]; 


    [swipeRecLeft release]; 
    [swipeRecRight release]; 
    [singleTap release]; 

    isDragging = NO; 
} 
else { 
    self = nil; 
} 

return self; 

}

Voici le reste des actions

-(void) tapSingle 

{ [self.delegate hitOccur]; }

-(void) swipe 
{ 
    isDragging = YES; 
} 

Et en plus dans mon UIScrollView j'ai setted délégué et lors du défilement extrémités I jeu isDragging propriété NO sur manualy chaque sous-vue de mon UIScrollView.

Ça marche ... mais ce n'est pas parfait. Pour faire défiler le contenu, je dois faire glisser deux fois dans UIImageView (le premier est de définir isDragging sur YES et ensuite nous pouvons faire défiler ...). Comment cela est-il correct?

Mise à jour:

Ok j'ai réussi à résoudre ce problème. Cependant je suis sûr que mon chemin n'est pas propre ou bon (mais cela fonctionne).

Dans ma sous-classe UIScrollView J'ai méthode overided hitTest avec ceci:

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

    if(!self.dragging) 
    { 
     if([[super hitTest:point withEvent:event] class] == [ResponsiveBookView class]) 
     { 
      container = [super hitTest:point withEvent:event]; 
     } 
    } 
    return self; 

} 

Lorsque le conteneur est conteneur identifiant et il me tient sous-classe UIView. Donc, je peux reconnaître si le toucher était sur mon image ou sur la vue de défilement elle-même. Maintenant, je dois DeTec si elle défile ou tout simplement toucher et je le fais ici:

-(void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event 
{ 

    if (!self.dragging) { 
     NSLog(@"touch touch touch"); 
     [container tapSingle]; 
     [self.nextResponder touchesEnded: touches withEvent:event]; 
    }  


    [super touchesEnded: touches withEvent: event]; 
} 

Comme vous le voyez si self.dragging (défilement) le comportement par défaut appliquera. Si! Self.dragging je vais appeler manuellement sur mon conteneur tapSingle (qui fera alors une action "se produire"). Ça marche!

Répondre

0

Ouais-utiliser des reconnaisseurs de gestes. Si vous ajoutez un UITapGestureRecognizer à chaque UIImageView (en utilisant la méthode UIVIew-addGestureRecognizer:), vous devriez obtenir à la fois la reconnaissance des taps et le comportement de défilement par défaut.

+0

Ok, merci beaucoup. Pourriez-vous me montrer comment je peux reconnaître le geste (balayage que je présume) avec un événement donné (UIEvent)? Un code simple suffirait. – Ertai

+0

J'ai mis à jour mon problème avec du code prenant dans votre suggestion. – Ertai

+0

Vous n'avez pas besoin d'un outil de reconnaissance de balayage pour la vue défilante - elle gère le défilement par elle-même. Configurez simplement la vue de défilement comme vous le feriez normalement (en ajoutant des sous-vues et en définissant la propriété 'contentSize'), en ajoutant les identificateurs de prise sur ses sous-vues. Vous devrez peut-être activer l'interaction de l'utilisateur sur les vues de l'image, mais cela devrait être le cas. –