2010-09-01 16 views
14

Mam podklasę UIScrollView, którą programowo przewijam używając animacji UIView.Zdarzenia dotykowe UIScrollView podczas animacji nie uruchamianej z animacjąWithDuration: ale działa dobrze z UIView beginAnimations:

Chciałbym, aby użytkownik mógł dotknąć lub powiększyć zawartość UIImageView w widoku przewijania podczas gdy animacja ma miejsce.

To działało w porządku, podczas gdy stosując preparat podobny do tego:

- (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]; 
} 

Teraz, ponieważ iOS 4.0, UIView beginAnimations: nie jest zalecane. Tak więc próbowałem zaktualizować mój kod za pomocą bloku i UIView animateWithDuration: Przewijanie działa identycznie jak powyżej.

Różnica klucz i irytujące jest to, że podczas animacji, UIScrollView i inne widoki no-longer odpowiedzi na metodach obsługi zdarzeń:

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

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

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

Ani też:

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

sprawdzony podczas próby Powiększenie.

Edycja w celu zwiększenia czytelności: brak prezentacji UIView odpowiada na zdarzenia dotyku. Nie ogranicza się to tylko do UIScrollView. UIScrollView peer a UIToolbar nie reaguje na zdarzenia dotykowe, ani inne przyciski, które są subviewsami peera do UIScrollView. Wygląda na to, że cały nadrzędny UIView jest zamrożony z interakcji użytkownika , podczas gdy animacja trwa. Ponownie, po zakończeniu animacji wszystkie powyższe UIViews ponownie reagują.

Wszystko to zostaje wywołane w UIView beginAnimations: sformułowanie bez względu na stan animacji.

Moja animacjaWithDuration: kod jest nieco inny - ale różnice nie są istotne. Jak tylko zakończy się animacja, powyższe zdarzenia dotykowe są znowu nazywa ...

oto mój kod ożywione:

- (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]; 
          } 
         } 
    }]; 
} 

Jedynym obsługi zdarzeń, które pożary podczas wspomnianego bloku animacji:

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

Pytanie: Czy powinienem - zignorować etykietę firmy Apple i odradzać etykietę i kontynuować używanie formuły beginAnimation? Czy powinienem - zreimplementować powiększanie i inne moje zdarzenia dotykowe za pomocą funkcji hitTest? Czy istnieje wiedza na temat różnicy we wdrażaniu bloków animacji, które mogą mi pomóc w konfrontacji z tym problemem? Czy jest coś oczywistego, czego mi brakuje?

Jestem nowym programistą dla firmy Apple, więc nie wiem, jak poważnie zabrać ze sobą zniechęcony tag. Ale jeśli ten API będzie przestarzały, zniknie, wolałbym ruszyć w długim kierunku.

Dziękuję bardzo za uwagę.

+0

Ten warunek rzeczywiście wydaje się być monitowany przez sytuację niskiej pamięci. Nie miałem czasu na kompleksowe sprawdzenie, czy to rzeczywiście jest przyczyna (dlatego nie odpowiedziałem jeszcze na pytanie). Ale po doświadczeniu podobnego zawieszenia obsługi zdarzeń w sytuacjach z niską pamięcią, wydaje się, że tak właśnie się dzieje. Teraz - dlaczego miałaby ona wpłynąć na animację blokową, podczas gdy druga nie jest ... Przeprowadzę kompleksowy test, gdy dostanę czas i post. – Jackifus

Odpowiedz

41

Wystarczy włączyć opcję UIViewAnimationOptionAllowUserInteraction podczas wywoływania animację tak:

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

To podstępne jeden, wiem! ;)

Re: Znacznik "Zniechęcony" - Ogólnie rzecz biorąc, gdy Apple mówi, aby nie robić czegoś w odniesieniu do projektowania aplikacji działających na ich platformach, zwykle jest to dla twojego dobra. Więc masz rację, pragnąc przyjąć bloki animacji zamiast starego, niezdarnego sposobu.

+0

Niewiarygodne - dziękuję, mucho! – Jackifus

+0

czekaj, masz na myśli, że animacje oparte na blokach blokują? To jest jak kalambur! (Przepraszam, nie mogłem się oprzeć. +1 za bardzo pomocną odpowiedź) – Bdebeez

+0

Doskonała odpowiedź, wielkie dzięki! – joern

Powiązane problemy