2009-12-15 4 views
0

J'essaie de trouver la meilleure façon de gérer les gestes de pincement dans un UITextView. Actuellement, j'ai essayé de tout gérer dans UITextView, mais je reçois des résultats inconsistants. Il semble qu'il peut attraper mes touches dans la méthode des touches a commencé, mais il ne se fait pas toujours attraper dans la méthode des touches déplacées.Résultats incohérents avec des pincements dans un UITextView

Serait-il préférable de gérer les touches dans une vue, et que UITextView transmette les événements multitouch? Serait-il préférable de faire quelque chose de compliqué comme de placer UITextView dans un scrollview? À ce stade, tout ce que je voudrais faire est d'ajuster la taille de la police sur un pincement ou une extension multitouch, ce que je peux obtenir pour travailler, mais ce n'est pas cohérent et je pense que j'ai réussi à confondre le UITextView plus que réellement obtenir des résultats.

Mon contrôle est une sous-classe de UITextView et met en œuvre UITextViewDelegate:

#import "MyUITextView.h" 
@implementation MyUITextView 

/* skipping unimportant code */ 


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if([touches count] == 2) 
    { 
     NSLog(@"two touches"); 
     UITouch *first = [[touches allObjects] objectAtIndex:0]; 
     UITouch *second = [[touches allObjects] objectAtIndex:1]; 
     initialDistance = [self distanceBetweenTwoPoints:[first locationInView:self] toPoint:[second locationInView:self]]; 

    } 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    NSLog(@"touches moved"); 
    if([touches count] == 2) 
    { 
     self.scrollEnabled = NO; 
     UITouch *first = [[touches allObjects] objectAtIndex:0]; 
     UITouch *second = [[touches allObjects] objectAtIndex:1]; 
     CGFloat currentDistance = [self distanceBetweenTwoPoints:[first locationInView:self] toPoint:[second locationInView:self]]; 
     if(initialDistance == 0) 
      initialDistance = currentDistance; 
     else if(currentDistance > initialDistance) 
     { 
      NSLog(@"zoom in"); 
      self.scrollEnabled = YES; 
      self.font = [UIFont fontWithName:[self.font fontName] size:[self.font pointSize] + 1.0f]; 
      self.text = self.text; 
     } 
     else if(currentDistance < initialDistance) 
     { 
      NSLog(@"zoom out"); 
      self.scrollEnabled = YES; 
      self.font = [UIFont fontWithName:[self.font fontName] size:[self.font pointSize] = 1.0f]; 
      self.text = self.text; 
     } 
    }  
} 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    NSLog(@"touches ended."); 
    initialDistance = 0; 
    [super touchesEnded:touches withEvent:event]; 

} 

-(CGFloat)distanceBetweenTwoPoints:(CGPoint)fromPoint toPoint:(CGPoint)toPoint 
{ 
    float x = toPoint.x - fromPoint.x; 
    float y = toPoint.y - fromPoint.y; 
    return sqrt(x*x + y*y); 

} 

-(BOOL)canBecomeFirstResponder 
{ return NO; } 

Fondamentalement, j'ai essayé de désactiver le défilement quand j'ai deux touches sur l'écran, puis le réactiver quand je fait . En outre, désactivé la possibilité de devenir le premier répondeur afin que je n'aurais pas à se battre avec le menu copier-coller. S'il y a une meilleure façon de le faire en permettant le menu copier-coller lorsque vous utilisez une seule touche, je suis tout ouïe. Je pense que je travaille essentiellement avec un exemple plus avancé pour ma première entrée dans cette activité gestuelle.

De plus, puisque le contrôle gère tout son propre contenu, je ne pense pas qu'il soit nécessaire de transmettre les événements tactiles, car il les gère lui-même. Ai-je tort?

Enfin, ce UITextView de la mienne est créé par programmation et placé dans un UINavigationControl. Je ne sais pas si cela fait une différence ou non.

+0

Clarification: Lorsque vous dites qu'il n'attrape pas les touches, vous voulez dire (1) le la méthode n'est pas appelée (2) elle s'appelle mais ne contient pas les deux touches ou (3) elle contient des touches sans rapport? – TechZen

+0

Selon mes rapports NSLog dans le débogueur, il retiendra souvent mes contacts dans les contacts commencés plusieurs fois, mais affichera seulement les rapports de journal pour les Touches déplacées une ou deux fois et généralement pas du tout. Donc, puisque mon instruction Log doit se déclencher à chaque fois que cette méthode est appelée, je crois qu'elle n'est tout simplement pas appelée. J'ai également oublié une section de code. Juste avant la ligne scrollEnabled, il y a une instruction d'encapsulation if pour envelopper tout cela dans une double touche. Je vais arranger ça. – georryan

+0

Vos doigts ne peuvent pas bouger simultanément. Dans ce cas, touchesMoved sera appelé pour chaque doigt individuellement, et [touch count] retournera 1. Rappelez-vous que les touches (NSSet *) ne contiennent que les touches qui ont été mises à jour. –

Répondre

0

Je pense que je commencerais par enregistrer toutes les touches et tous les événements. Assurez-vous de consigner la propriété de vue des touches.

Vous pouvez également sous-classer UIWindow pour créer une classe de diagnostic qui enregistrera chaque touche dans l'application. Cela peut être très utile pour voir exactement où et quand les contacts se produisent réellement. Vous pourriez constater que les touches sont dirigées vers des vues différentes de celles que vous attendez.

Comme indiqué dans les commentaires à l'OP, touchesMoved: peut être appelé par une simple pression d'un mouvement multitouch en mouvement. Donc, si vous commencez un geste de deux doigts comme une pincée, mais que vous bougez seulement un doigt, vous obtenez seulement une touche en touchesMoved:. Par exemple, les gens effectuent souvent une pincée en plaçant leur pouce et leur index, puis en déplaçant l'index seulement. (Même s'ils se déplacent tous les deux, l'index se déplacera toujours sur une plus longue distance que le pouce car il est plus long.)

Questions connexes