ios ionic Cancelar uma animação do UIView?




title center ionic (13)

Desculpe ressuscitar esta resposta, mas no iOS 10 as coisas mudaram um pouco, e agora o cancelamento é possível e você pode até cancelar com elegância!

Após o iOS 10, você pode cancelar animações com o UIViewPropertyAnimator !

UIViewPropertyAnimator(duration: 2, dampingRatio: 0.4, animations: {
    view.backgroundColor = .blue
})
animator.stopAnimation(true)

Se você passar true, cancela a animação e pára exatamente onde você a cancelou. O método de conclusão não será chamado. No entanto, se você passar falso, você é responsável por terminar a animação:

animator.finishAnimation(.start)

Você pode terminar sua animação e permanecer no estado atual (.current) ou ir para o estado inicial (.start) ou para o estado final (.end)

By the way, você pode até fazer uma pausa e reiniciar mais tarde ...

animator.pauseAnimation()
animator.startAnimation()

Nota: Se você não quiser um cancelamento abrupto, poderá reverter sua animação ou até mesmo alterar sua animação depois de fazer uma pausa!

É possível cancelar uma animação do UIView enquanto ela está em andamento? Ou eu teria que cair para o nível CA?

ou seja, eu fiz algo assim (talvez definindo uma ação de animação final também):

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];

Mas antes que a animação seja concluída e eu recebo o evento de animação finalizada, quero cancelá-lo. Isso é possível? Pesquisando por aí, algumas pessoas fazem a mesma pergunta sem respostas - e uma ou duas pessoas especulam que isso não pode ser feito.


A maneira mais simples de parar todas as animações em uma determinada vista, imediatamente , é esta:

Vincule o projeto ao QuartzCore.framework. No início do seu código:

#import <QuartzCore/QuartzCore.h>

Agora, quando você quiser parar todas as animações em uma vista morta em suas trilhas, diga isto:

[CATransaction begin];
[theView.layer removeAllAnimations];
[CATransaction commit];

A linha do meio funcionaria por si só, mas há um atraso até que o runloop termine (o "momento de redesenho"). Para evitar esse atraso, coloque o comando em um bloco de transação explícito, conforme mostrado. Isso funciona desde que nenhuma outra alteração tenha sido executada nessa camada no runloop atual.


Mesmo se você cancelar a animação nas formas acima da animação, didStopSelector ainda será executado. Portanto, se você tiver estados lógicos em seu aplicativo impulsionado por animações, você terá problemas. Por esse motivo, com as formas descritas acima, uso a variável de contexto das animações UIView . Se você passar o estado atual de seu programa pelo parâmetro de contexto para a animação, quando a animação parar, a função didStopSelector poderá decidir se deve fazer algo ou apenas retornar com base no estado atual e o valor de estado passado como contexto.


Nenhuma das opções acima resolveu para mim, mas isso ajudou: A animação UIView define a propriedade imediatamente, depois a anima. Ele interrompe a animação quando a camada de apresentação corresponde ao modelo (a propriedade set).

Eu resolvi o meu problema, que era "eu quero animar de onde você parece que você aparece" ("você", ou seja, a visão). Se você quiser isso, então:

  1. Adicione QuartzCore.
  2. CALayer * pLayer = theView.layer.presentationLayer;

definir a posição para a camada de apresentação

Eu uso algumas opções, incluindo UIViewAnimationOptionOverrideInheritedDuration

Mas como a documentação da Apple é vaga, não sei se realmente substitui as outras animações quando usadas, ou apenas redefine os timers.

[UIView animateWithDuration:blah... 
                    options: UIViewAnimationOptionBeginFromCurrentState ... 
                    animations: ^ {
                                   theView.center = CGPointMake( pLayer.position.x + YOUR_ANIMATION_OFFSET, pLayer.position.y + ANOTHER_ANIMATION_OFFSET);
                   //this only works for translating, but you get the idea if you wanna flip and scale it. 
                   } completion: ^(BOOL complete) {}];

E isso deve ser uma solução decente para agora.


Para cancelar uma animação, basta definir a propriedade que está sendo animada atualmente, fora da animação do UIView. Isso irá parar a animação onde quer que esteja, e o UIView irá pular para a configuração que você acabou de definir.


Se você estiver animando uma restrição alterando a constante em vez de uma propriedade de exibição, nenhum dos outros métodos funcionará no iOS 8.

Exemplo de animação:

self.constraint.constant = 0;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
[UIView animateWithDuration:1.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                     self.constraint.constant = 1.0f;
                     [self.view layoutIfNeeded];
                 } completion:^(BOOL finished) {

                 }];

Solução:

Você precisa remover as animações das camadas de quaisquer vistas afetadas pela alteração de restrição e suas subcamadas.

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}

CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];

Versão rápida da solução de Stephen Darlington

UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(0.1)
// other animation properties

// set view properties
UIView.commitAnimations()

Quando eu trabalho com animação UIStackView , além de removeAllAnimations() eu preciso definir alguns valores para um inicial, porque removeAllAnimations() pode configurá-los para o estado imprevisível. Eu tenho stackView com view1 e view2 dentro, e uma visão deve estar visível e uma oculta:

public func configureStackView(hideView1: Bool, hideView2: Bool) {
    let oldHideView1 = view1.isHidden
    let oldHideView2 = view2.isHidden
    view1.layer.removeAllAnimations()
    view2.layer.removeAllAnimations()
    view.layer.removeAllAnimations()
    stackView.layer.removeAllAnimations()
    // after stopping animation the values are unpredictable, so set values to old
    view1.isHidden = oldHideView1 //    <- Solution is here
    view2.isHidden = oldHideView2 //    <- Solution is here

    UIView.animate(withDuration: 0.3,
                   delay: 0.0,
                   usingSpringWithDamping: 0.9,
                   initialSpringVelocity: 1,
                   options: [],
                   animations: {
                    view1.isHidden = hideView1
                    view2.isHidden = hideView2
                    stackView.layoutIfNeeded()
    },
                   completion: nil)
}

Usar:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];


Para pausar uma animação sem reverter o estado para original ou final:

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;

No iOS 4 e superior, use a opção UIViewAnimationOptionBeginFromCurrentState na segunda animação para reduzir a primeira animação.

Por exemplo, suponha que você tenha uma visão com um indicador de atividade. Você deseja desvanecer no indicador de atividade enquanto alguma atividade potencialmente demorada começa e diminui quando a atividade é concluída. No código abaixo, a visão com o indicador de atividade é chamada de activityView .

- (void)showActivityIndicator {
    activityView.alpha = 0.0;
    activityView.hidden = NO;
    [UIView animateWithDuration:0.5
                 animations:^(void) {
                     activityView.alpha = 1.0;
                 }];

- (void)hideActivityIndicator {
    [UIView animateWithDuration:0.5
                 delay:0 options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^(void) {
                     activityView.alpha = 0.0;
                 }
                 completion:^(BOOL completed) {
                     if (completed) {
                         activityView.hidden = YES;
                     }
                 }];
}




uiviewanimation