UIScrollView eventi touch durante l'animazione non sparare con animateWithDuration: ma funzionano bene con UIView beginAnimations:

StackOverflow https://stackoverflow.com/questions/3614116

Domanda

Ho una sottoclasse UIScrollView che sto programmazione Scorrimento usando animazioni UIView.

Mi piacerebbe che l'utente sia in grado di attingere o zoom nel contenuto UIImageView del Rotolo Visualizza , mentre l'animazione è in corso.

Questo ha lavorato bene durante l'utilizzo di una formulazione simile a questo:

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

Ora, dal momento che iOS 4.0, UIView beginAnimations: è scoraggiato. Così ho cercato di aggiornare il mio codice utilizzando un blocco e UIView animateWithDuration: Lo scorrimento funziona in modo identico a quanto sopra.

La chiave e la differenza esasperante è che durante l'animazione, l'UIScrollView e altre viste non più rispondere ai metodi di manipolazione di evento:

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

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

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

Né:

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

get chiamato quando si cerca di zoom.

Modifica per chiarezza: No UIView presenti risponde al tocco eventi. Questo non è limitato al solo UIScrollView. pari del UIScrollView un UIToolbar non risponde a eventi touch, né altri pulsanti che sono subviews di un pari alla UIScrollView. Sembra che l'intero UIView genitore è congelato fuori interazione con l'utente , mentre l'animazione è in corso . Ancora una volta, dopo il completamento di animazione, tutti i UIViews sopra sono nuovamente reattivo.

Questi tutti fatevi chiamata negli beginAnimations UIView:. Formulazione indipendentemente dallo stato di animazione

Il mio animateWithDuration: il codice è un po 'diverso - ma le differenze non sono rilevanti. Non appena il completamento del animazione, gli eventi touch di cui sopra sono di nuovo chiamati ...

Ecco il mio codice animato:

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

L'unico gestore di eventi che viene generato durante il blocco di animazione qui sopra è:

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

Quindi, domanda: Dovrei - ignoro di Apple scoraggiato etichetta e continuare a utilizzare la formulazione BeginAnimation? Dovrei - reimplementare zoom e gli altri miei eventi touch-based utilizzando hitTest? C'è una certa conoscenza della differenza di realizzazione tra i blocchi di animazione che possono aiutare me affrontare questo problema? C'è qualcosa di ovvio che mi manca?

Sono un nuovo sviluppatore di Apple, e quindi non so quanto seriamente a prendere il loro scoraggiato tag. Ma se questa API sarà deprecato poi scomparire, preferirei muoversi in una direzione duratura.

Grazie mille per la vostra attenzione.

È stato utile?

Soluzione

Hai solo bisogno di includere l'opzione UIViewAnimationOptionAllowUserInteraction quando si richiama l'animazione in questo modo:

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

Questo è uno subdolo, lo so! ;)

Re: Il tag "Scoraggiato" - In generale, quando Apple dice di non fare qualcosa per quanto riguarda la progettazione di applicazioni che girano sulle loro piattaforme, di solito è per il tuo bene. Quindi lei ha ragione nel voler adottare blocchi di animazione al posto del vecchio modo goffo.

Altri suggerimenti

risposta

di quickthyme è corretta. Ecco il frammento di Swift

Swift 4

UIView.animate(
    withDuration: 0.3, // specify animation duration here 
    delay: 0, // specify delay if needed 
    options: [
        UIView.AnimationOptions.allowUserInteraction, 
        UIView.AnimationOptions.curveLinear
    ], 
    animations: {
        // animations code    
    }
)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top