Estou girando um CALayer e tentando pará-lo em sua posição final após a animação ser concluída.
Mas depois que a animação é concluída, ela é redefinida para sua posição inicial.
(Os documentos do xcode dizem explicitamente que a animação não atualizará o valor da propriedade.)
alguma sugestão de como conseguir isso.
ios
iphone
calayer
cabasicanimation
Nilesh Ukey
fonte
fonte
.presentation()
para obter o valor "final, visto". Pesquise abaixo as respostas corretas abaixo, que explicam isso com a camada de apresentação.Respostas:
Aqui está a resposta, é uma combinação da minha resposta e da de Krishnan.
O valor padrão é
kCAFillModeRemoved
. (Qual é o comportamento de redefinição que você está vendo.)fonte
O problema com removedOnCompletion é que o elemento da interface do usuário não permite a interação do usuário.
A técnica é definir o valor FROM na animação e o valor TO no objeto. A animação preencherá automaticamente o valor TO antes de iniciar e, quando removida, deixará o objeto no estado correto.
fonte
alphaAnimation.beginTime = 1;
, além disso,fillMode
não é necessário, tanto quanto eu posso dizer ...?beginTime
não é relativo, você deve usar, por exemplo::CACurrentMediaTime()+1;
fillMode
, veja mais em Impedir que as camadas retornem aos valores originais ao usar CAAnimations explícitasDefina a seguinte propriedade:
fonte
basta colocá-lo dentro do seu código
fonte
Você pode simplesmente definir a chave de
CABasicAnimation
queposition
quando você adicioná-lo à camada. Ao fazer isso, ele substituirá a animação implícita feita na posição da passagem atual no loop de execução.Você pode obter mais informações sobre a Sessão de vídeo Apple WWDC 421 2011 - Core Animation Essentials (no meio do vídeo)
fonte
someLayer.position = endPosition;
. E obrigado pelo juiz da WWDC!Um CALayer possui uma camada de modelo e uma camada de apresentação. Durante uma animação, a camada de apresentação é atualizada independentemente do modelo. Quando a animação é concluída, a camada de apresentação é atualizada com o valor do modelo. Se você deseja evitar um salto estridente após o término da animação, a chave é manter as duas camadas sincronizadas.
Se você conhece o valor final, basta definir o modelo diretamente.
Mas se você tiver uma animação em que não conhece a posição final (por exemplo, um desvanecimento lento que o usuário pode pausar e depois reverter), poderá consultar a camada de apresentação diretamente para encontrar o valor atual e atualizar o modelo.
Puxar o valor da camada de apresentação também é particularmente útil para os caminhos-chave de escala ou rotação. (por exemplo
transform.scale
,transform.rotation
)fonte
Sem usar o
removedOnCompletion
Você pode tentar esta técnica:
fonte
Então, meu problema era que eu estava tentando girar um objeto no gesto de panorâmica e, portanto, tinha várias animações idênticas em cada movimento. Eu tinha os dois
fillMode = kCAFillModeForwards
eisRemovedOnCompletion = false
mas não ajudou. No meu caso, eu tinha que ter certeza de que a chave da animação é diferente cada vez que adiciono uma nova animação :fonte
Simplesmente configurar
fillMode
eremovedOnCompletion
não funcionou para mim. Resolvi o problema definindo todas as propriedades abaixo para o objeto CABasicAnimation:Esse código se transforma
myView
em 85% de seu tamanho (terceira dimensão inalterada).fonte
A animação principal mantém duas hierarquias de camada: a camada do modelo e a camada de apresentação . Quando a animação está em andamento, a camada do modelo está realmente intacta e mantém seu valor inicial. Por padrão, a animação é removida quando concluída. Em seguida, a camada de apresentação volta ao valor da camada do modelo.
Simplesmente definir
removedOnCompletion
comoNO
significa que a animação não será removida e desperdiçará memória. Além disso, a camada do modelo e a camada de apresentação não serão mais síncronas, o que pode levar a possíveis erros.Portanto, seria uma solução melhor atualizar a propriedade diretamente na camada do modelo para o valor final.
Se houver alguma animação implícita causada pela primeira linha do código acima, tente desativar se:
fonte
Isso funciona:
A animação principal mostra uma 'camada de apresentação' no topo da sua camada normal durante a animação. Portanto, defina a opacidade (ou o que for) para o que você deseja que seja visto quando a animação terminar e a camada de apresentação desaparecer. Faça isso na linha antes de adicionar a animação para evitar tremulações quando ela for concluída.
Se você deseja atrasar, faça o seguinte:
Por fim, se você usar 'removedOnCompletion = false', ele vazará CAAnimations até que a camada seja descartada - evite.
fonte
A resposta de @Leslie Godwin não é realmente boa ", self.view.layer.opacity = 1;" for feito imediatamente (leva cerca de um segundo), corrija alphaAnimation.duration para 10.0, se você tiver dúvidas. Você precisa remover esta linha.
Portanto, quando você fixa fillMode em kCAFillModeForwards e removeOnCompletion em NO, deixa a animação permanecer na camada. Se você corrigir o delegado da animação e tentar algo como:
... a camada é restaurada imediatamente no momento em que você executa esta linha. É o que queríamos evitar.
Você deve corrigir a propriedade da camada antes de remover a animação. Tente o seguinte:
fonte
Parece que o sinalizador removedOnCompletion definido como false e fillMode definido como kCAFillModeForwards também não funciona para mim.
Depois de aplicar uma nova animação em uma camada, um objeto de animação é redefinido para seu estado inicial e, em seguida, é animado a partir desse estado. O que precisa ser feito adicionalmente é definir a propriedade desejada da camada de modelo de acordo com a propriedade da camada de apresentação antes de definir uma nova animação da seguinte forma:
fonte
A solução mais fácil é usar animações implícitas. Isso resolverá todo esse problema para você:
Se você deseja personalizar, por exemplo, a duração, pode usar
NSAnimationContext
:Nota: Isso é testado apenas no macOS.
Inicialmente, não vi nenhuma animação ao fazer isso. O problema é que a camada de uma camada com suporte de exibição não é animada implicitamente. Para resolver isso, adicione você mesmo uma camada (antes de definir a exibição como suportada por camada).
Um exemplo de como fazer isso seria:
O uso
self.wantsLayer
não fez nenhuma diferença nos meus testes, mas pode ter alguns efeitos colaterais que eu não conheço.fonte
Aqui está uma amostra do playground:
false
comoisRemovedOnCompletion
- deixe a Animação principal limpa após o término da animaçãofonte