Post on 22-Jan-2018
Globalcode – Open4education
Animações no iOSVictor Maraccini
iOS Developer @ Nubank
Globalcode – Open4education
Agenda
Por que animações?
Debaixo dos panos com UIView animations
Problemas comuns e como resolvê-los
Novidades no iOS 10
Globalcode – Open4education
Agenda
Por que animações?
Debaixo dos panos com UIView animations
Problemas comuns e como resolvê-los
Novidades no iOS 10
Globalcode – Open4education
Agenda
Animações funcionais
…têm o propósito de auxiliar a passagem de informação ao usuário
Globalcode – Open4education
Agenda
Animações funcionais…orientar
Dá contexto ao usuário sobre uma mudança
acontecendo na interface
Globalcode – Open4education
Agenda
Animações funcionais…orientar
Dá contexto ao usuário sobre uma mudança
acontecendo na interface
Elementos de referência
Globalcode – Open4education
Agenda
…chamar a atenção
Alerta o usuário sobre uma parte importante da
sua lógica de negócios
Animações funcionais
Globalcode – Open4education
Agenda
Por que animações?
Debaixo dos panos com UIView animations
Problemas comuns e como resolvê-los
Novidades no iOS 10
Globalcode – Open4education
UIView animations
Globalcode – Open4education
UIView animations
Introduzidas no iOS 4
Block-based
Métodos de classe
Anima automaticamente algumas propriedades
Globalcode – Open4education
UIView animations
[UIView animateWithDuration: delay: options: animations:^{ } completion:^(BOOL finished) { }];
Globalcode – Open4education
UIView animations
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ } completion:^(BOOL finished) { }];
Globalcode – Open4education
UIView animations
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) { }];
Globalcode – Open4education
UIView animations
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {
... }];
Globalcode – Open4education
UIView animations
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {
... }];
Globalcode – Open4education
UIView animations
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {
... }];
.alpha = 0
Globalcode – Open4education
UIView animations
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {
... }];
UIView.alpha = 0
Globalcode – Open4education
UIView animations
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {
... }];
UIView.alpha = 0 CALayer
Globalcode – Open4education
UIView animations
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {
... }];
UIView.alpha = 0 CALayer CAAnimation
Globalcode – Open4education
UIView animations
UIView.alpha = 0 CALayer CAAnimation
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key
Globalcode – Open4education
UIView animations
UIView.alpha = 0 CALayer CAAnimation
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key
.delegate
Globalcode – Open4education
UIView animations
UIView.alpha = 0 CALayer CAAnimation
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key { if ([key isEqualToString:@"..."]) { return [CAAnimation animation]; } return [super actionForLayer:layer forKey:key]; //[NSNull null] }
Globalcode – Open4education
UIView animations
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key { if ([key isEqualToString:@"..."]) { CAAnimation *animation = [CAAnimation animation]; animation.beginTime = ...; animation.duration = ...; animation.timingFunction = ...;
} return [super actionForLayer:layer forKey:key]; //[NSNull null] }
EaseInOut00.5 [UIView animateWithDuration:
delay: options:
...UIViewAnimationOptionCurve
Globalcode – Open4education
UIView animations
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key { if ([key isEqualToString:@"..."]) { CAAnimation *animation = [CAAnimation animation]; animation.beginTime = 0.5; animation.duration = 0; animation.timingFunction = [CAMediaTimingFunction functionWithName:@"easeInEaseOut"]; } return [super actionForLayer:layer forKey:key]; //[NSNull null] }
[UIView animateWithDuration: delay: options:
...UIViewAnimationOptionCurve
Globalcode – Open4education
UIView
UIView
Globalcode – Open4education
UIView
Backing Layer .layer
UIView
Globalcode – Open4education
UIView
Backing Layer
Model Layer Presentation Layer
.layer
.modelLayer .presentationLayer
UIView
Globalcode – Open4education
UIView
Backing Layer
Model Layer Presentation Layer
Estado Transição
.modelLayer .presentationLayer
UIView
.layer
Globalcode – Open4education
UIView
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
Duas hierarquias independentes
Globalcode – Open4education
UIView
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
Duas hierarquias independentes
Globalcode – Open4education
UIView
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
Duas hierarquias independentes
Globalcode – Open4education
UIView
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
UIView
Backing Layer
Model Layer Presentation Layer
Duas hierarquias independentes
Globalcode – Open4education
Layer
Model Layer Presentation Layer
.modelLayer .presentationLayer
CALayer
.opacity = 1 .opacity = 1
Fluxo de uma mudança de propriedade
Globalcode – Open4education
Layer
Model Layer Presentation Layer
.modelLayer .presentationLayer
CALayer
.opacity = 1 .opacity = 1
.opacity = 1 .opacity = 0
Globalcode – Open4education
Layer
Model Layer Presentation Layer
.modelLayer .presentationLayer
CALayer.opacity = 0
.opacity = 1 .opacity = 1
Globalcode – Open4education
Layer
Model Layer Presentation Layer
.modelLayer .presentationLayer
CALayer.opacity = 0
.opacity = 0 .opacity = 1
Globalcode – Open4education
Layer
Model Layer Presentation Layer
.modelLayer .presentationLayer
CALayer.opacity = 0
.opacity = 0 .opacity = 1
CAAnimation
actionForLayer:forKey:
Globalcode – Open4education
Layer
Model Layer Presentation Layer
.modelLayer .presentationLayer
CALayer.opacity = 0
.opacity = 0 .opacity = 1
CAAnimation
Globalcode – Open4education
Layer
Model Layer Presentation Layer
.modelLayer .presentationLayer
CALayer.opacity = 0
.opacity = 0 .opacity = 0
CAAnimation
Globalcode – Open4education
Hierarquia
Globalcode – Open4education
Hierarquia
Toda UIView tem um backing layer
Globalcode – Open4education
Hierarquia
Toda UIView tem um backing layer
Todo CALayer tem:
Model layer
Presentation layer
Globalcode – Open4education
CALayer
Set da propriedade dentro de um bloco
Globalcode – Open4education
CALayer
Set da propriedade dentro de um bloco
UIView muda o CALayer
Globalcode – Open4education
CALayer
Set da propriedade dentro de um bloco
UIView muda o CALayer
Model layer é afetado imediatamente
Presentation layer faz a mudança gradual
Globalcode – Open4education
Agenda
Por que animações?
Debaixo dos panos com UIView animations
Problemas comuns e como resolvê-los
Novidades no iOS 10
Globalcode – Open4education
Encadear animações
Globalcode – Open4education
Encadeamento de animações
Globalcode – Open4education
Encadeamento de animações
Não há uma forma simples e elegante
Globalcode – Open4education
Encadeamento de animações
Não há uma forma simples e elegante
Keyframe animations
Globalcode – Open4education
Encadeamento de animações
Não há uma forma simples e elegante
Keyframe animations
Não têm suporte a spring
Globalcode – Open4education
Encadeamento de animações
Não há uma forma simples e elegante
Keyframe animations
Não têm suporte a spring
Não têm suporte a curvas
Globalcode – Open4education
Encadeamento de animações
Não há uma forma simples e elegante
Keyframe animations
Não têm suporte a spring
Não têm suporte a curvas
Você precisa lidar com os delays
Globalcode – Open4education
Encadeamento de animações
Não há uma forma simples e elegante
Nestar UIView Animations
Globalcode – Open4education
Encadeamento de animações
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; } completion:^(BOOL finished) { }];
Nestar UIView Animations
Globalcode – Open4education
Encadeamento de animações
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; } completion:^(BOOL finished) { [UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{ [animationView2 setFrameY:400]; } completion:^(BOOL finished) { }]; }];
Nestar UIView Animations
Globalcode – Open4education
Encadeamento de animações
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; } completion:^(BOOL finished) { [UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{ [animationView2 setFrameY:400]; } completion:^(BOOL finished) { [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:0 animations:^{ [animationView3 setFrameY:400]; } completion:nil]; }]; }];
Nestar UIView Animations
Globalcode – Open4education
Encadeamento de animações
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; } completion:^(BOOL finished) { [UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{ [animationView2 setFrameY:400]; } completion:^(BOOL finished) { [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:0 animations:^{ [animationView3 setFrameY:400]; } completion:nil]; }]; }];
Nestar UIView Animations
Globalcode – Open4education
Encadeamento de animações
Wrapper de UIView animations
Fica com a responsabilidade de concatenar blocos de animação
Propriedades não animáveis, controlar progresso de animações, …
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Encadeamento de animações
self.controller = [[NUAnimationController alloc] init];
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Encadeamento de animações
self.controller = [[NUAnimationController alloc] init];
[self.controller addAnimations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; }]
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Encadeamento de animações
self.controller = [[NUAnimationController alloc] init];
[self.controller addAnimations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; }] .withAnimationOption(UIViewAnimationOptionTransitionCrossDissolve)
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Encadeamento de animações
self.controller = [[NUAnimationController alloc] init];
[self.controller addAnimations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; }] .withAnimationOption(UIViewAnimationOptionTransitionCrossDissolve)
[self.controller addAnimations:^{ [animationView2 setFrameY:400]; }] .withCurve(UIViewAnimationCurveEaseInOut)
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Encadeamento de animações
self.controller = [[NUAnimationController alloc] init];
[self.controller addAnimations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; }] .withAnimationOption(UIViewAnimationOptionTransitionCrossDissolve)
[self.controller addAnimations:^{ [animationView2 setFrameY:400]; }] .withCurve(UIViewAnimationCurveEaseInOut)
[self.controller addAnimations:^{ [animationView3 setFrameY:400]; }] .withType(NUAnimationTypeSpringy) .withDuration(NUSpringAnimationNaturalDuration)
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Encadeamento de animações
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOption animations:^{
} completion:^(BOOL finished) { [UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOption animations:^{
} completion:^(BOOL finished) { [UIView animateWithDuration:0.5 delay:0 using WithDamping:0.5 initialSpringVelocity:0 options:0 animations:^{ } completion:nil]; }]; }];
[animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor];
[animationView2 setFrameY:400];
[animationView3 setFrameY:400];
Spring
CurveEaseInOut
TransitionCrossDissolve
Globalcode – Open4education
Encadeamento de animações
[animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor];
[animationView2 setFrameY:400];
[animationView3 setFrameY:400];
Spring
CurveEaseInOut
TransitionCrossDissolve
Globalcode – Open4education
Encadeamento de animações
self.controller = [[NUAnimationController alloc] init];
[self.controller addAnimations:^{ [animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor]; }] .withAnimationOption(UIViewAnimationOptionTransitionCrossDissolve)
[self.controller addAnimations:^{ [animationView2 setFrameY:400]; }] .withCurve(UIViewAnimationCurveEaseInOut)
[self.controller addAnimations:^{ [animationView3 setFrameY:400]; }] .withType(NUAnimationTypeSpringy) .withDuration(NUSpringAnimationNaturalDuration)
Globalcode – Open4education
Propriedades não-animáveis
Globalcode – Open4education
“Animar" texto de labels
Propriedades não-animáveis
Globalcode – Open4education
Propriedades não-animáveis
ImplementaçãoNSTimer?
Globalcode – Open4education
Propriedades não-animáveis
ImplementaçãoNSTimer?
[NSTimer timerWithTimeInterval:1/60.f target:self selector:@selector(updateProgress) userInfo:nil repeats:YES];
Globalcode – Open4education
appa
Implementação
Não tem resolução suficiente (~50 ms)
(Precisamos de ~16 ms)
NSTimer?
[NSTimer timerWithTimeInterval:1/60.f target:self selector:@selector(updateProgress) userInfo:nil repeats:YES];
Because of the various input sources a typical run loop manages, the effective resolution of
the time interval for a timer is limited to on the order of 50-100 milliseconds
Globalcode – Open4education
Propriedades não-animáveis
Implementação
CADisplayLink
Globalcode – Open4education
Propriedades não-animáveis
Implementação
A CADisplayLink object is a timer object that allows your application to synchronize its drawing to the refresh rate of the display…
CADisplayLink
Globalcode – Open4education
Propriedades não-animáveis
Implementação
A CADisplayLink object is a timer object that allows your application to synchronize its drawing to the
CADisplayLink
refresh rate of the display…
Globalcode – Open4education
Implementação
FrameFrameFrame (1/60 s)
Propriedades não-animáveis
CADisplayLink
Runloop principal
…
Globalcode – Open4education
Implementação
FrameFrameFrame (1/60 s)
Propriedades não-animáveis
CADisplayLink
Runloop principal
Callback …
Globalcode – Open4education
Implementação
FrameFrameFrame (1/60 s)
Propriedades não-animáveis
CADisplayLink
Runloop principal
Callback …
CADisplayLink
Globalcode – Open4education
Implementação
FrameFrameFrame (1/60 s)
Propriedades não-animáveis
CADisplayLink
Runloop principal
Callback …Callback Callback
Globalcode – Open4education
Implementação
FrameFrameFrame (1/60 s)
Propriedades não-animáveis
CADisplayLink
Runloop principal
Callback …Callback
frameInterval = 2;
Globalcode – Open4education
Implementação
FrameFrameFrame (1/60 s)
Propriedades não-animáveis
CADisplayLink
Runloop principal
Callback …Callback Callback
Δt
Globalcode – Open4education
Implementação
FrameFrameFrame (1/60 s)
Propriedades não-animáveis
CADisplayLink
Runloop principal
…Callback CallbackCallback
Globalcode – Open4education
Propriedades não-animáveis
ImplementaçãoCADisplayLink
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAnimationProgress)];
Globalcode – Open4education
Propriedades não-animáveis
ImplementaçãoCADisplayLink
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAnimationProgress)];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
Globalcode – Open4education
Propriedades não-animáveis
ImplementaçãoCADisplayLink
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAnimationProgress)];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
- (void)updateAnimationProgress {
self.progress += (self.displayLink.timestamp - self.lastTimestamp) / self.options.duration; self.lastTimestamp = self.displayLink.timestamp; }
Globalcode – Open4education
Propriedades não-animáveis
ImplementaçãoCADisplayLink
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAnimationProgress)];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
- (void)updateAnimationProgress {
self.progress += (self.displayLink.timestamp - self.lastTimestamp) / self.options.duration; self.lastTimestamp = self.displayLink.timestamp; }
Diferença de tempo
Globalcode – Open4education
Propriedades não-animáveis
ImplementaçãoCADisplayLink
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAnimationProgress)];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
- (void)updateAnimationProgress { if (self.lastTimestamp == 0) { self.lastTimestamp = self.displayLink.timestamp; self.progress = 0; return; } self.progress += (self.displayLink.timestamp - self.lastTimestamp) / self.options.duration; self.lastTimestamp = self.displayLink.timestamp; }
Globalcode – Open4education
Propriedades não-animáveis
ImplementaçãoCADisplayLink
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAnimationProgress)];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[self.displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
Globalcode – Open4education
Propriedades não-animáveis
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Propriedades não-animáveis
[self.animator addAnimations:^{ progressView.progress = viewModel.progress; [progressView layoutIfNeeded]; }].withDuration(NULongAnimationDuration)
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Propriedades não-animáveis
[self.animator addAnimations:^{ progressView.progress = viewModel.progress; [progressView layoutIfNeeded]; }].withDuration(NULongAnimationDuration) .alongSideBlock(^(CGFloat progress){
});
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Propriedades não-animáveis
[self.animator addAnimations:^{ progressView.progress = viewModel.progress; [progressView layoutIfNeeded]; }].withDuration(NULongAnimationDuration) .alongSideBlock(^(CGFloat progress){ amountLabel.text = [viewModel amountTextForProgress:progress]; });
https://github.com/nubank/NUAnimationKit
Globalcode – Open4education
Animações com AutoLayout
Globalcode – Open4education
AutoLayout é ótimo para views estáticas
Animações com AutoLayout
Globalcode – Open4education
AutoLayout é ótimo para views estáticas
Cuidado pra não brigar com ele nas animações!
Animações com AutoLayout
Globalcode – Open4education
AutoLayout é ótimo para views estáticas
Cuidado pra não brigar com ele nas animações!
Se alguma coisa mudar, ele desfaz sua animação!
Animações com AutoLayout
Globalcode – Open4education
Se alguma coisa mudar, ele desfaz sua animação!
Animações com AutoLayout
Globalcode – Open4education
Se alguma coisa mudar, ele desfaz sua animação!
Animações com AutoLayout
Globalcode – Open4education
Se alguma coisa mudar, ele desfaz sua animação!
Animações com AutoLayout
Globalcode – Open4education
Se alguma coisa mudar, ele desfaz sua animação!
Animações com AutoLayout
[UIView animateWithDuration:0.5 animations:^{ self.leftView.center = ..., }];
Globalcode – Open4education
Se alguma coisa mudar, ele desfaz sua animação!
Animações com AutoLayout
[UIView animateWithDuration:0.5 animations:^{ self.leftView.center = ..., }];
Globalcode – Open4education
O que aconteceu?
Animações com AutoLayout
Globalcode – Open4education
O que aconteceu?
Clicar no textfield causa um layout pass
Animações com AutoLayout
Globalcode – Open4education
O que aconteceu?
Clicar no textfield causa um layout pass
Animações com AutoLayout
[self.view setNeedsLayout];
Globalcode – Open4education
O que aconteceu?
Clicar no textfield causa um layout pass
Autolayout não sabia das suas mudanças…
Logo, ele descarta
Animações com AutoLayout
[self.view setNeedsLayout];
Globalcode – Open4education
Animações com AutoLayout
Globalcode – Open4education
Animações com AutoLayout
O sistema seta os frames (Layout inicial)
self.leftView.bounds = ... self.leftView.center = ...
Globalcode – Open4education
UIView Animation block
Animações com AutoLayout
Você seta o center da view
self.leftView.center = ...
Globalcode – Open4education
UIView Animation block
Animações com AutoLayout
O sistema invalida o layout (Tap no UITextField)
[self.view setNeedsLayout];
Globalcode – Open4education
UIView Animation block
Animações com AutoLayout
O sistema seta os frames (Segundo layout)
self.leftView.bounds = ... self.leftView.center = ...
Globalcode – Open4education
Duas formas de lidar com isso:
Animações com AutoLayout
Globalcode – Open4education
Duas formas de lidar com isso:
Não mudar o frame dos objetos
Animações com AutoLayout
Globalcode – Open4education
Duas formas de lidar com isso:
Não mudar o frame dos objetos
Usar CGAffineTransform
Animações com AutoLayout
Globalcode – Open4education
Duas formas de lidar com isso:
Não mudar o frame dos objetos
Usar CGAffineTransform
Mudar constraints
Animações com AutoLayout
Globalcode – Open4education
CGAffineTransform
Globalcode – Open4education
CGAffineTransform
Aplicado por cima do bounds e center
Globalcode – Open4education
CGAffineTransform
Aplicado por cima do bounds e center
self.leftView.center = CGPointMake(self.leftView.center.x + 100, self.leftView.center.y);
[UIView animateWithDuration:0.5 animations:^{
}];
Globalcode – Open4education
[UIView animateWithDuration:0.5 animations:^{
}];
Aplicado por cima do bounds e center
CGAffineTransform
self.leftView.transform = CGAffineTransformMakeTranslation(100, 0);
Globalcode – Open4education
CGAffineTransform
Aplicado por cima do bounds e center
[UIView animateWithDuration:0.5 animations:^{
}];
self.leftView.transform = CGAffineTransformMakeTranslation(100, 0);
Globalcode – Open4education
Duas formas de lidar com isso:
Não mudar o frame dos objetos
Usar CGAffineTransform
Animações com AutoLayout
Mudar constraints
Globalcode – Open4education
Atualiza as constraints dentro do bloco
Mudar constraints
Globalcode – Open4education
Atualiza as constraints dentro do bloco
Mudar constraints
[UIView animateWithDuration:0.5 animations:^{ self.leftConstraint.constant += 100; }];
Globalcode – Open4education
Atualiza as constraints dentro do bloco
Mudar constraints
[UIView animateWithDuration:0.5 animations:^{ self.leftConstraint.constant += 100; }];
Animação não acontece pois o set do frame é feito fora do bloco!
Globalcode – Open4education
O que aconteceu?
Animações com AutoLayout
Globalcode – Open4education
Animações com AutoLayout
Globalcode – Open4education
Animações com AutoLayout
O sistema seta os frames (Layout inicial)
self.leftView.bounds = ... self.leftView.center = ...
Globalcode – Open4education
Animações com AutoLayout
Você muda a constraint
self.leftConstraint.constant += 100;
UIView Animation block
Globalcode – Open4education
Animações com AutoLayout
O sistema invalida o layout… mas não seta os novos frames
UIView Animation block
[self.view setNeedsLayout];
Globalcode – Open4education
Animações com AutoLayout
UIView Animation block
self.leftView.bounds = ... self.leftView.center = ...
O sistema seta os frames (Segundo layout)
Globalcode – Open4education
Atualiza as constraints dentro do bloco
Mudar constraints
Globalcode – Open4education
Atualiza as constraints dentro do bloco
Chama
Mudar constraints
[self.view layoutIfNeeded];
Globalcode – Open4education
Atualiza as constraints dentro do bloco
Chama
Isso força um novo layout pass
Mudar constraints
[self.view layoutIfNeeded];
Globalcode – Open4education
Atualiza as constraints dentro do bloco
Mudar constraints
[UIView animateWithDuration:0.5 animations:^{ self.leftConstraint.constant += 100;
}];[self.view layoutIfNeeded];
Globalcode – Open4education
Atualiza as constraints dentro do bloco
Mudar constraints
[UIView animateWithDuration:0.5 animations:^{ self.leftConstraint.constant += 100;
}];[self.view layoutIfNeeded];
Globalcode – Open4education
Agenda
Por que animações?
Debaixo dos panos com UIView animations
Problemas comuns e como resolvê-los
Novidades no iOS 10
Globalcode – Open4education
Novidades no iOS 10
Nova arquitetura de animações
[UIView animateWithDuration: delay: options: animations:^{ } completion:^(BOOL finished) { }];
Métodos de classe
Globalcode – Open4education
Novidades no iOS 10
Nova arquitetura de animações
@protocol UIViewAnimating <NSObject> @protocol UIViewImplicitlyAnimating <UIViewAnimating>
@protocol UITimingCurveProvider <NSCoding, NSCopying>
Protocolos
Globalcode – Open4education
Novidades no iOS 10
Nova arquitetura de animações
UIViewPropertyAnimator
@protocol UIViewAnimating <NSObject> @protocol UIViewImplicitlyAnimating <UIViewAnimating>
@protocol UITimingCurveProvider <NSCoding, NSCopying>
Globalcode – Open4education
Novidades no iOS 10
Nova arquitetura de animações
UITimingCurveProvider
@protocol UIViewAnimating <NSObject> @protocol UIViewImplicitlyAnimating <UIViewAnimating>
@protocol UITimingCurveProvider <NSCoding, NSCopying>
UIViewPropertyAnimator
Globalcode – Open4education
Novidades no iOS 10
Nova arquitetura de animações
UITimingCurveProvider
@protocol UIViewAnimating <NSObject> @protocol UIViewImplicitlyAnimating <UIViewAnimating>
@protocol UITimingCurveProvider <NSCoding, NSCopying>
UIViewPropertyAnimator
Cubic / Spring
Globalcode – Open4education
Novidades no iOS 10
UITimingCurveProvider
@property(nonatomic, readonly) UITimingCurveType timingCurveType;
Globalcode – Open4education
Novidades no iOS 10
UITimingCurveProvider
@property(nonatomic, readonly) UITimingCurveType timingCurveType;
@property(nullable, nonatomic, readonly) UICubicTimingParameters *cubicTimingParameters; //Builtin, Cubic ou Composed
Globalcode – Open4education
Novidades no iOS 10
UITimingCurveProvider
@property(nonatomic, readonly) UITimingCurveType timingCurveType;
@property(nullable, nonatomic, readonly) UICubicTimingParameters *cubicTimingParameters; //Builtin, Cubic ou Composed
@property(nullable, nonatomic, readonly) UISpringTimingParameters *springTimingParameters; //Spring ou Composed
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
- (void)pauseAnimation;
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
- (void)pauseAnimation;- (void)finishAnimationAtPosition:(UIViewAnimatingPosition)finalPosition;
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
- (void)pauseAnimation;- (void)finishAnimationAtPosition:(UIViewAnimatingPosition)finalPosition;
@property(nonatomic) CGFloat fractionComplete;
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
- (void)pauseAnimation;- (void)finishAnimationAtPosition:(UIViewAnimatingPosition)finalPosition;
@property(nonatomic) CGFloat fractionComplete;
Útil para transições de View Controllers
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
self.animator = [[UIViewPropertyAnimator alloc] initWithDuration:... curve:... animations:^{ ...
}];
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
self.animator = [[UIViewPropertyAnimator alloc] initWithDuration:... curve:... animations:^{ ...
}];
[self.animator addAnimations:^{
} delayFactor:0.5];
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
self.animator = [[UIViewPropertyAnimator alloc] initWithDuration:... curve:... animations:^{ ...
}];
[self.animator addAnimations:^{
} delayFactor:0.5];
Mudanças são aditivas
O sistema cria uma transição entre um passo de animação e outro.
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
[self.animator pauseAnimation];
self.animator.fractionComplete = 0.5;
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
[self.animator continueAnimationWithTimingParameters:... durationFactor:0.5];
[self.animator pauseAnimation]; self.animator.fractionComplete = 0.5;
Globalcode – Open4education
Novidades no iOS 10
UIViewPropertyAnimator
[self.animator continueAnimationWithTimingParameters:... durationFactor:0.5];
[self.animator pauseAnimation]; self.animator.fractionComplete = 0.5;
[self.animator finishAnimationAtPosition:UIViewAnimatingPositionCurrent]; UIViewAnimatingPositionEnd UIViewAnimatingPositionStart
Globalcode – Open4education
Resumo
Globalcode – Open4education
Resumo
Por que animações?
Globalcode – Open4education
Resumo
Por que animações?
Debaixo dos panos com UIView animations
Globalcode – Open4education
Resumo
Por que animações?
Debaixo dos panos com UIView animations
Problemas comuns e como resolvê-los
Globalcode – Open4education
Resumo
Por que animações?
Debaixo dos panos com UIView animations
Problemas comuns e como resolvê-los
Novidades no iOS 10
Globalcode – Open4education
Obrigado!