Os eventos do UIScrollView Touch durante a animação não atiram com o AnimateWithDuration: mas funcione bem com as iniciações do UIView:

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

Pergunta

Eu tenho uma subclasse do UIScrollView que estou rolando programaticamente usando as animações do UIView.

Eu gostaria que o usuário pudesse tocar ou ampliar o uiimageView conteúdo da visualização de rolagem enquanto A animação está ocorrendo.

Isso funcionou bem ao usar uma formulação semelhante a isso:

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

Agora, desde o iOS 4.0, o UIView BeginAmations: está desanimado. Então tentei atualizar meu código usando um bloco e o UIView AnimateWithDuration: o rolagem funciona de forma idêntica ao acima.

A diferença chave e enlouquecedora é que, durante a animação, o UIScrollView e outras visualizações que não respondem aos métodos de manuseio de eventos:

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

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

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

Nem faz :

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

Seja chamado ao tentar aumentar o zoom.

Editar para maior clareza: Nenhuma visão do uiview responde aos eventos de toque. Isso não se limita apenas ao UIScrollView. O Peer do UIScrollView A Uitoolbar não responde aos eventos de toque, nem outros botões que são subvisivos de um colega do UIScrollView. Parece que toda a UIView dos pais está congelada fora da interação do usuário Enquanto a animação está acontecendo. Novamente, após a conclusão da animação, todas as UIViews acima respondem novamente.

Tudo isso é chamado nas iniciações UIView: formulação, independentemente do estado de animação.

Meu AnimateWithDuration: o código é um pouco diferente - mas as diferenças não são materiais. Assim que a animação concluir, os eventos de toque acima são novamente chamados ...

Aqui está meu código animado:

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

O único manipulador de eventos que dispara durante o bloco de animação acima é:

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

Então, pergunta: devo - ignorar a Apple's desanimado Rotule e continue a usar a formulação de iniciação? Devo - reimplementar o zoom e meus outros eventos baseados em toque usando o Hittest? Existe algum conhecimento da diferença na implementação entre blocos de animação que podem me ajudar a enfrentar esse problema? Há algo óbvio que estou perdendo?

Eu sou um novo desenvolvedor da Apple, e então não sei como levar a sério o seu desanimado marcação. Mas se essa API for descontinuada, desaparecer, eu prefiro seguir em uma direção duradoura.

Muito obrigado pela sua atenção.

Foi útil?

Solução

Você só precisa incluir a opção UiviewanimationOptionAlowUserInteraction ao invocar a animação como assim:

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

Isso é sorrateiro, eu sei! ;)

Re: A tag "desencorajada" - em geral, quando a Apple diz para você não fazer algo em relação ao design de aplicativos que são executados em suas plataformas, geralmente é para o seu próprio bem. Então você está certo em querer adotar blocos de animação em vez da maneira antiga e desajeitada.

Outras dicas

quickthymeA resposta está correta. Aqui está o trecho de 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    
    }
)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top