TDC 2016 - Animações no iOS

Preview:

Citation preview

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!

Recommended