2010-09-01 6 views
14

Ich habe eine UIScrollView-Unterklasse, die ich programmgesteuert mit UIView-Animationen scrollte.UIScrollView Berührungsereignisse während der Animation, die nicht mit animateWithDuration feuert: aber funktioniert gut mit UIView beginAnimations:

Ich möchte, dass der Benutzer den UIImageView-Inhalt der Bildlaufansicht antippen oder zoomen kann, während die Animation stattfindet.

Dieser hat gut funktioniert, während eine Formulierung verwandt dies mit:

- (void) scrollSmoothlyatPixelsPerSecond:(float)thePixelsPerSecond { 
    // distance in pixels/speed in pixels per second 
    float animationDuration = _scrollView.contentSize.width/thePixelsPerSecond; 

    [UIView beginAnimations:@"scrollAnimation" context:nil]; 
    [UIView setAnimationCurve: UIViewAnimationCurveLinear]; 
    [UIView setAnimationDuration:animationDuration]; 
    _scrollView.contentOffset = CGPointMake(_scrollView.contentSize.width, 0); 
    [UIView commitAnimations]; 
} 

Jetzt, da iOS 4.0, UIView beginAnimations: abgeraten. Also habe ich versucht, meinen Code mit einem Block und UIView animateWithDuration zu aktualisieren: Das Scrollen funktioniert genauso wie oben beschrieben.

Der Schlüssel und wahnsinniger Unterschied ist, dass während der Animation, die UIScrollView und andere Ansichten nichtmehr auf Event-Handling Methoden reagieren:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; 

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

auch nicht:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView; 

aufgerufen werden, wenn zu versuchen, Zoomen.

Für Klarheit bearbeiten: Kein UIView present reagiert auf Berührungsereignisse. Dies beschränkt sich nicht nur auf UIScrollView. Der UIScrollView-Peer eine UIToolbar reagiert nicht auf Berührungsereignisse, noch andere Schaltflächen, die Teilansichten eines Peers zu UIScrollView sind. Es scheint, dass die gesamte übergeordnete UIView außerhalb der Benutzerinteraktion während der Animation eingefroren ist. Nachdem die Animation abgeschlossen ist, reagieren alle oben genannten UIViews erneut.

Diese werden in den UIView beginAnimations aufgerufen: Formulierung unabhängig vom Animationszustand.

Meine animateWithDuration: Code ist etwas anders - aber die Unterschiede sind nicht materiell. Sobald die Animation abgeschlossen ist, werden die oben genannten Touch-Ereignisse wieder genannt ...

hier ist mein belebtes Code:

- (void) scrollSmoothlyToSyncPoint:(SyncPoint *) theSyncPoint andContinue:(BOOL)theContinueFlag{ 

    float animationDuration = theSyncPoint.time - [player currentTime]; 
    [UIView animateWithDuration:animationDuration 
          delay:0 
         options:UIViewAnimationOptionCurveLinear 
        animations:^{ 
     [_scrollView setContentOffset:theSyncPoint.contentOffset]; 
    } 
        completion:^(BOOL finished){ 
         if (theContinueFlag) { 
          SyncPoint *aSyncPoint = [self nextSyncPoint]; 
          if (aSyncPoint) { 
           [self scrollSmoothlyToSyncPoint:aSyncPoint andContinue:YES]; 
          } 
         } 
    }]; 
} 

Der einzige Event-Handler, die während der obigen Animation Block Feuer ist:

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

Also, Frage: Sollte ich - ignorieren Apples entmutigt Label und weiterhin die beginAnimation Formulierung verwenden? Sollte ich das Zoomen und meine anderen touchbasierten Ereignisse mit hitTest neu implementieren? Gibt es ein gewisses Wissen über den Unterschied in der Umsetzung zwischen Animationsblöcken, die mir helfen können, dieses Problem zu lösen? Ist etwas offensichtlich, dass ich vermisse?

Ich bin ein neuer Entwickler für Apple, und ich weiß nicht, wie ernst ihre entmutigt Tag nehmen. Aber wenn diese API veraltet ist, dann verschwinde ich lieber in eine dauerhafte Richtung.

Vielen Dank für Ihre Aufmerksamkeit.

+0

Diese Bedingung scheint wirklich von einer Situation mit wenig Arbeitsspeicher ausgelöst zu werden. Ich hatte nicht die Zeit, umfassend zu testen, ob das tatsächlich der Grund ist (deshalb habe ich die Frage noch nicht beantwortet). Aber nach einer ähnlichen Aussetzung der Ereignisbehandlung während Situationen mit wenig Speicher scheint es wirklich so zu sein. Nun - warum sollte die blockbasierte Animation betroffen sein, während die andere nicht ... Ich werde einen ausführlichen Test durchführen, wenn ich die Zeit und den Beitrag bekomme. – Jackifus

Antwort

41

Sie müssen nur die UIViewAnimationOptionAllowUserInteraction Option, um, wenn die Animation wie so Aufruf:

[UIView animateWithDuration:animationDuration 
          delay:0 
         options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction) 
        <snip>]; 

Das ist eine hinterhältige eine ist, ich weiß! ;)

Re: Das "Entmutigte" -Tag - Im Allgemeinen, wenn Apple Ihnen sagt, nichts zu tun, um Anwendungen zu entwerfen, die auf ihren Plattformen laufen, ist es normalerweise zu Ihrem Besten. Sie sind also richtig, wenn Sie Animationsblöcke statt der klobigen alten Art übernehmen wollen.

+0

Sneaky in der Tat - vielen Dank! – Jackifus

+0

warte, du meinst, dass blockbasierte animationen BLOCKieren sind? Es ist wie ein Code-Wortspiel! (Sorry, konnte nicht widerstehen. +1 für eine sehr hilfreiche Antwort) – Bdebeez

+0

ausgezeichnete Antwort, vielen Dank! – joern

Verwandte Themen