2009-06-23 6 views
0

J'ai une sous-classe de UIScrollView qui remplacechange iPhone OS3 à UIScrollView sous-classes

touchesBegan: withEvent: touchesMoved: withEvent:
touchesEnded: withEvent:

Outrepasser ces trois semble être une technique largement utilisé (basé sur mes observations dans les forums). Cependant, dès que j'ai compilé ce code sur OS3, ces méthodes ne sont plus appelées. Quelqu'un d'autre a-t-il vu ce problème? Existe-t-il une correction connue n'utilisant pas de méthodes non documentées?

Ma première tentative de solution est de déplacer toutes les touchesBegan/DEPLACE/vers le bas dans les méthodes terminées mon point de vue du contenu et mis

delaysContentTouches = NO; canCancelContentTouches = NO;

Cela a fonctionné partiellement, mais m'a laissé incapable de pan lorsque j'ai zoomé. Ma deuxième tentative a seulement mis canCancelContentTouches = NO quand il y avait deux touches (passant ainsi le geste de pincement au contenu). Cette méthode était sommaire et ne fonctionnait pas très bien.

Des idées? Mon exigence est que la vue de défilement doit gérer les touches de panoramique, et je dois gérer les touches de zoom.

Répondre

1

Ma solution n'est pas jolie. Fondamentalement, il y a une vue de défilement qui contient une vue de contenu. La vue déroulante n'implémente pas les touchBegan, Moved, Ended du tout. La vue de contenu conserve un pointeur sur son parent (appelé "parentScrollView" dans cet exemple). La vue de contenu gère la logique et utilise [parentScrollView setCanCancelContentTouches: ...] pour déterminer si la vue parent doit ou non annuler un événement tactile (et ainsi effectuer un événement de défilement). La logique du nombre de prises est là parce que les utilisateurs placent rarement les deux doigts à l'écran exactement au même moment, donc le premier contact doit être ignoré s'il est très rapidement suivi d'une seconde.

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    if(parentViewIsUIScrollView) 
    { 
     UIScrollView * parentScrollView = (UIScrollView*)self.superview; 
     if([touches count] == 1) 
     { 
      if([[touches anyObject] tapCount] == 1) 
      { 
       if(numberOfTouches > 0) 
       { 
        [parentScrollView setCanCancelContentTouches:NO]; 
        //NSLog(@"cancel NO - touchesBegan - second touch"); 
        numberOfTouches = 2; 
       } 
       else 
       { 
        [parentScrollView setCanCancelContentTouches:YES]; 
        //NSLog(@"cancel YES - touchesBegan - first touch"); 
        numberOfTouches = 1; 
       } 
      } 
      else 
      { 
       numberOfTouches = 1; 
       [parentScrollView setCanCancelContentTouches:NO]; 
       //NSLog(@"cancel NO - touchesBegan - doubletap"); 
      } 
     } 
     else 
     {  
      [parentScrollView setCanCancelContentTouches:NO]; 
      //NSLog(@"cancel NO - touchesBegan"); 
      numberOfTouches = 2; 
     } 
     //NSLog(@"numberOfTouches_touchesBegan = %i",numberOfTouches); 
    } 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if(touchesCrossed) 
     return; 

    if(parentViewIsUIScrollView) 
    { 
     UIScrollView * parentScrollView = (UIScrollView*)self.superview; 
     NSArray * thoseTouches = [[event touchesForView:self] allObjects]; 

     if([thoseTouches count] != 2) 
      return; 
     numberOfTouches = 2; 


     /* compute and perform pinch event */ 

     [self setNeedsDisplay]; 
     [parentScrollView setContentSize:self.frame.size]; 
    } 
} 
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    touchesCrossed = NO; 
    if(parentViewIsUIScrollView) 
    { 
     numberOfTouches = MAX(numberOfTouches-[touches count],0); 
     [(UIScrollView*)self.superview setCanCancelContentTouches:YES]; 
     //NSLog(@"cancel YES - touchesEnded"); 
     //NSLog(@"numberOfTouches_touchesEnded = %i",numberOfTouches); 
    } 
} 
+0

C'est génial! Une façon très élégante de gérer la situation. –