160
Globalcode – Open4education Animações no iOS Victor Maraccini iOS Developer @ Nubank

TDC 2016 - Animações no iOS

Embed Size (px)

Citation preview

Page 1: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações no iOSVictor Maraccini

iOS Developer @ Nubank

Page 2: TDC 2016 - Animações no iOS

Globalcode – Open4education

Agenda

Por que animações?

Debaixo dos panos com UIView animations

Problemas comuns e como resolvê-los

Novidades no iOS 10

Page 3: TDC 2016 - Animações no iOS

Globalcode – Open4education

Agenda

Por que animações?

Debaixo dos panos com UIView animations

Problemas comuns e como resolvê-los

Novidades no iOS 10

Page 4: TDC 2016 - Animações no iOS

Globalcode – Open4education

Agenda

Animações funcionais

…têm o propósito de auxiliar a passagem de informação ao usuário

Page 5: TDC 2016 - Animações no iOS

Globalcode – Open4education

Agenda

Animações funcionais…orientar

Dá contexto ao usuário sobre uma mudança

acontecendo na interface

Page 6: TDC 2016 - Animações no iOS

Globalcode – Open4education

Agenda

Animações funcionais…orientar

Dá contexto ao usuário sobre uma mudança

acontecendo na interface

Elementos de referência

Page 7: TDC 2016 - Animações no iOS

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

Page 8: TDC 2016 - Animações no iOS

Globalcode – Open4education

Agenda

Por que animações?

Debaixo dos panos com UIView animations

Problemas comuns e como resolvê-los

Novidades no iOS 10

Page 9: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

Page 10: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

Introduzidas no iOS 4

Block-based

Métodos de classe

Anima automaticamente algumas propriedades

Page 11: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration: delay: options: animations:^{ } completion:^(BOOL finished) { }];

Page 12: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ } completion:^(BOOL finished) { }];

Page 13: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) { }];

Page 14: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {

... }];

Page 15: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {

... }];

Page 16: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {

... }];

.alpha = 0

Page 17: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {

... }];

UIView.alpha = 0

Page 18: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {

... }];

UIView.alpha = 0 CALayer

Page 19: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ animationView1.alpha = 0; } completion:^(BOOL finished) {

... }];

UIView.alpha = 0 CALayer CAAnimation

Page 20: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

UIView.alpha = 0 CALayer CAAnimation

- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key

Page 21: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView animations

UIView.alpha = 0 CALayer CAAnimation

- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key

.delegate

Page 22: TDC 2016 - Animações no iOS

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

Page 23: TDC 2016 - Animações no iOS

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

Page 24: TDC 2016 - Animações no iOS

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

Page 25: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView

UIView

Page 26: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView

Backing Layer .layer

UIView

Page 27: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView

Backing Layer

Model Layer Presentation Layer

.layer

.modelLayer .presentationLayer

UIView

Page 28: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView

Backing Layer

Model Layer Presentation Layer

Estado Transição

.modelLayer .presentationLayer

UIView

.layer

Page 29: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView

UIView

Backing Layer

Model Layer Presentation Layer

UIView

Backing Layer

Model Layer Presentation Layer

Duas hierarquias independentes

Page 30: TDC 2016 - Animações no iOS

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

Page 31: TDC 2016 - Animações no iOS

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

Page 32: TDC 2016 - Animações no iOS

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

Page 33: TDC 2016 - Animações no iOS

Globalcode – Open4education

Layer

Model Layer Presentation Layer

.modelLayer .presentationLayer

CALayer

.opacity = 1 .opacity = 1

Fluxo de uma mudança de propriedade

Page 34: TDC 2016 - Animações no iOS

Globalcode – Open4education

Layer

Model Layer Presentation Layer

.modelLayer .presentationLayer

CALayer

.opacity = 1 .opacity = 1

.opacity = 1 .opacity = 0

Page 35: TDC 2016 - Animações no iOS

Globalcode – Open4education

Layer

Model Layer Presentation Layer

.modelLayer .presentationLayer

CALayer.opacity = 0

.opacity = 1 .opacity = 1

Page 36: TDC 2016 - Animações no iOS

Globalcode – Open4education

Layer

Model Layer Presentation Layer

.modelLayer .presentationLayer

CALayer.opacity = 0

.opacity = 0 .opacity = 1

Page 37: TDC 2016 - Animações no iOS

Globalcode – Open4education

Layer

Model Layer Presentation Layer

.modelLayer .presentationLayer

CALayer.opacity = 0

.opacity = 0 .opacity = 1

CAAnimation

actionForLayer:forKey:

Page 38: TDC 2016 - Animações no iOS

Globalcode – Open4education

Layer

Model Layer Presentation Layer

.modelLayer .presentationLayer

CALayer.opacity = 0

.opacity = 0 .opacity = 1

CAAnimation

Page 39: TDC 2016 - Animações no iOS

Globalcode – Open4education

Layer

Model Layer Presentation Layer

.modelLayer .presentationLayer

CALayer.opacity = 0

.opacity = 0 .opacity = 0

CAAnimation

Page 40: TDC 2016 - Animações no iOS

Globalcode – Open4education

Hierarquia

Page 41: TDC 2016 - Animações no iOS

Globalcode – Open4education

Hierarquia

Toda UIView tem um backing layer

Page 42: TDC 2016 - Animações no iOS

Globalcode – Open4education

Hierarquia

Toda UIView tem um backing layer

Todo CALayer tem:

Model layer

Presentation layer

Page 43: TDC 2016 - Animações no iOS

Globalcode – Open4education

CALayer

Set da propriedade dentro de um bloco

Page 44: TDC 2016 - Animações no iOS

Globalcode – Open4education

CALayer

Set da propriedade dentro de um bloco

UIView muda o CALayer

Page 45: TDC 2016 - Animações no iOS

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

Page 46: TDC 2016 - Animações no iOS

Globalcode – Open4education

Agenda

Por que animações?

Debaixo dos panos com UIView animations

Problemas comuns e como resolvê-los

Novidades no iOS 10

Page 47: TDC 2016 - Animações no iOS

Globalcode – Open4education

Encadear animações

Page 48: TDC 2016 - Animações no iOS

Globalcode – Open4education

Encadeamento de animações

Page 49: TDC 2016 - Animações no iOS

Globalcode – Open4education

Encadeamento de animações

Não há uma forma simples e elegante

Page 50: TDC 2016 - Animações no iOS

Globalcode – Open4education

Encadeamento de animações

Não há uma forma simples e elegante

Keyframe animations

Page 51: TDC 2016 - Animações no iOS

Globalcode – Open4education

Encadeamento de animações

Não há uma forma simples e elegante

Keyframe animations

Não têm suporte a spring

Page 52: TDC 2016 - Animações no iOS

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

Page 53: TDC 2016 - Animações no iOS

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

Page 54: TDC 2016 - Animações no iOS

Globalcode – Open4education

Encadeamento de animações

Não há uma forma simples e elegante

Nestar UIView Animations

Page 55: TDC 2016 - Animações no iOS

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

Page 56: TDC 2016 - Animações no iOS

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

Page 57: TDC 2016 - Animações no iOS

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

Page 58: TDC 2016 - Animações no iOS

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

Page 59: TDC 2016 - Animações no iOS

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

Page 60: TDC 2016 - Animações no iOS

Globalcode – Open4education

Encadeamento de animações

self.controller = [[NUAnimationController alloc] init];

https://github.com/nubank/NUAnimationKit

Page 61: TDC 2016 - Animações no iOS

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

Page 62: TDC 2016 - Animações no iOS

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

Page 63: TDC 2016 - Animações no iOS

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

Page 64: TDC 2016 - Animações no iOS

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

Page 65: TDC 2016 - Animações no iOS

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

Page 66: TDC 2016 - Animações no iOS

Globalcode – Open4education

Encadeamento de animações

[animationView1 setFrameY:400]; animationView1.backgroundColor = [UIColor grayColor];

[animationView2 setFrameY:400];

[animationView3 setFrameY:400];

Spring

CurveEaseInOut

TransitionCrossDissolve

Page 67: TDC 2016 - Animações no iOS

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)

Page 68: TDC 2016 - Animações no iOS

Globalcode – Open4education

Propriedades não-animáveis

Page 69: TDC 2016 - Animações no iOS

Globalcode – Open4education

“Animar" texto de labels

Propriedades não-animáveis

Page 70: TDC 2016 - Animações no iOS

Globalcode – Open4education

Propriedades não-animáveis

ImplementaçãoNSTimer?

Page 71: TDC 2016 - Animações no iOS

Globalcode – Open4education

Propriedades não-animáveis

ImplementaçãoNSTimer?

[NSTimer timerWithTimeInterval:1/60.f target:self selector:@selector(updateProgress) userInfo:nil repeats:YES];

Page 72: TDC 2016 - Animações no iOS

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

Page 73: TDC 2016 - Animações no iOS

Globalcode – Open4education

Propriedades não-animáveis

Implementação

CADisplayLink

Page 74: TDC 2016 - Animações no iOS

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

Page 75: TDC 2016 - Animações no iOS

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…

Page 76: TDC 2016 - Animações no iOS

Globalcode – Open4education

Implementação

FrameFrameFrame (1/60 s)

Propriedades não-animáveis

CADisplayLink

Runloop principal

Page 77: TDC 2016 - Animações no iOS

Globalcode – Open4education

Implementação

FrameFrameFrame (1/60 s)

Propriedades não-animáveis

CADisplayLink

Runloop principal

Callback …

Page 78: TDC 2016 - Animações no iOS

Globalcode – Open4education

Implementação

FrameFrameFrame (1/60 s)

Propriedades não-animáveis

CADisplayLink

Runloop principal

Callback …

CADisplayLink

Page 79: TDC 2016 - Animações no iOS

Globalcode – Open4education

Implementação

FrameFrameFrame (1/60 s)

Propriedades não-animáveis

CADisplayLink

Runloop principal

Callback …Callback Callback

Page 80: TDC 2016 - Animações no iOS

Globalcode – Open4education

Implementação

FrameFrameFrame (1/60 s)

Propriedades não-animáveis

CADisplayLink

Runloop principal

Callback …Callback

frameInterval = 2;

Page 81: TDC 2016 - Animações no iOS

Globalcode – Open4education

Implementação

FrameFrameFrame (1/60 s)

Propriedades não-animáveis

CADisplayLink

Runloop principal

Callback …Callback Callback

Δt

Page 82: TDC 2016 - Animações no iOS

Globalcode – Open4education

Implementação

FrameFrameFrame (1/60 s)

Propriedades não-animáveis

CADisplayLink

Runloop principal

…Callback CallbackCallback

Page 83: TDC 2016 - Animações no iOS

Globalcode – Open4education

Propriedades não-animáveis

ImplementaçãoCADisplayLink

_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAnimationProgress)];

Page 84: TDC 2016 - Animações no iOS

Globalcode – Open4education

Propriedades não-animáveis

ImplementaçãoCADisplayLink

_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAnimationProgress)];

[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

Page 85: TDC 2016 - Animações no iOS

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

Page 86: TDC 2016 - Animações no iOS

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

Page 87: TDC 2016 - Animações no iOS

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

Page 88: TDC 2016 - Animações no iOS

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

Page 89: TDC 2016 - Animações no iOS

Globalcode – Open4education

Propriedades não-animáveis

https://github.com/nubank/NUAnimationKit

Page 90: TDC 2016 - Animações no iOS

Globalcode – Open4education

Propriedades não-animáveis

[self.animator addAnimations:^{ progressView.progress = viewModel.progress; [progressView layoutIfNeeded]; }].withDuration(NULongAnimationDuration)

https://github.com/nubank/NUAnimationKit

Page 91: TDC 2016 - Animações no iOS

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

Page 92: TDC 2016 - Animações no iOS

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

Page 93: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações com AutoLayout

Page 94: TDC 2016 - Animações no iOS

Globalcode – Open4education

AutoLayout é ótimo para views estáticas

Animações com AutoLayout

Page 95: TDC 2016 - Animações no iOS

Globalcode – Open4education

AutoLayout é ótimo para views estáticas

Cuidado pra não brigar com ele nas animações!

Animações com AutoLayout

Page 96: TDC 2016 - Animações no iOS

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

Page 97: TDC 2016 - Animações no iOS

Globalcode – Open4education

Se alguma coisa mudar, ele desfaz sua animação!

Animações com AutoLayout

Page 98: TDC 2016 - Animações no iOS

Globalcode – Open4education

Se alguma coisa mudar, ele desfaz sua animação!

Animações com AutoLayout

Page 99: TDC 2016 - Animações no iOS

Globalcode – Open4education

Se alguma coisa mudar, ele desfaz sua animação!

Animações com AutoLayout

Page 100: TDC 2016 - Animações no iOS

Globalcode – Open4education

Se alguma coisa mudar, ele desfaz sua animação!

Animações com AutoLayout

[UIView animateWithDuration:0.5 animations:^{ self.leftView.center = ..., }];

Page 101: TDC 2016 - Animações no iOS

Globalcode – Open4education

Se alguma coisa mudar, ele desfaz sua animação!

Animações com AutoLayout

[UIView animateWithDuration:0.5 animations:^{ self.leftView.center = ..., }];

Page 102: TDC 2016 - Animações no iOS

Globalcode – Open4education

O que aconteceu?

Animações com AutoLayout

Page 103: TDC 2016 - Animações no iOS

Globalcode – Open4education

O que aconteceu?

Clicar no textfield causa um layout pass

Animações com AutoLayout

Page 104: TDC 2016 - Animações no iOS

Globalcode – Open4education

O que aconteceu?

Clicar no textfield causa um layout pass

Animações com AutoLayout

[self.view setNeedsLayout];

Page 105: TDC 2016 - Animações no iOS

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

Page 106: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações com AutoLayout

Page 107: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações com AutoLayout

O sistema seta os frames (Layout inicial)

self.leftView.bounds = ... self.leftView.center = ...

Page 108: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView Animation block

Animações com AutoLayout

Você seta o center da view

self.leftView.center = ...

Page 109: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView Animation block

Animações com AutoLayout

O sistema invalida o layout (Tap no UITextField)

[self.view setNeedsLayout];

Page 110: TDC 2016 - Animações no iOS

Globalcode – Open4education

UIView Animation block

Animações com AutoLayout

O sistema seta os frames (Segundo layout)

self.leftView.bounds = ... self.leftView.center = ...

Page 111: TDC 2016 - Animações no iOS

Globalcode – Open4education

Duas formas de lidar com isso:

Animações com AutoLayout

Page 112: TDC 2016 - Animações no iOS

Globalcode – Open4education

Duas formas de lidar com isso:

Não mudar o frame dos objetos

Animações com AutoLayout

Page 113: TDC 2016 - Animações no iOS

Globalcode – Open4education

Duas formas de lidar com isso:

Não mudar o frame dos objetos

Usar CGAffineTransform

Animações com AutoLayout

Page 114: TDC 2016 - Animações no iOS

Globalcode – Open4education

Duas formas de lidar com isso:

Não mudar o frame dos objetos

Usar CGAffineTransform

Mudar constraints

Animações com AutoLayout

Page 115: TDC 2016 - Animações no iOS

Globalcode – Open4education

CGAffineTransform

Page 116: TDC 2016 - Animações no iOS

Globalcode – Open4education

CGAffineTransform

Aplicado por cima do bounds e center

Page 117: TDC 2016 - Animações no iOS

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:^{

}];

Page 118: TDC 2016 - Animações no iOS

Globalcode – Open4education

[UIView animateWithDuration:0.5 animations:^{

}];

Aplicado por cima do bounds e center

CGAffineTransform

self.leftView.transform = CGAffineTransformMakeTranslation(100, 0);

Page 119: TDC 2016 - Animações no iOS

Globalcode – Open4education

CGAffineTransform

Aplicado por cima do bounds e center

[UIView animateWithDuration:0.5 animations:^{

}];

self.leftView.transform = CGAffineTransformMakeTranslation(100, 0);

Page 120: TDC 2016 - Animações no iOS

Globalcode – Open4education

Duas formas de lidar com isso:

Não mudar o frame dos objetos

Usar CGAffineTransform

Animações com AutoLayout

Mudar constraints

Page 121: TDC 2016 - Animações no iOS

Globalcode – Open4education

Atualiza as constraints dentro do bloco

Mudar constraints

Page 122: TDC 2016 - Animações no iOS

Globalcode – Open4education

Atualiza as constraints dentro do bloco

Mudar constraints

[UIView animateWithDuration:0.5 animations:^{ self.leftConstraint.constant += 100; }];

Page 123: TDC 2016 - Animações no iOS

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!

Page 124: TDC 2016 - Animações no iOS

Globalcode – Open4education

O que aconteceu?

Animações com AutoLayout

Page 125: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações com AutoLayout

Page 126: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações com AutoLayout

O sistema seta os frames (Layout inicial)

self.leftView.bounds = ... self.leftView.center = ...

Page 127: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações com AutoLayout

Você muda a constraint

self.leftConstraint.constant += 100;

UIView Animation block

Page 128: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações com AutoLayout

O sistema invalida o layout… mas não seta os novos frames

UIView Animation block

[self.view setNeedsLayout];

Page 129: TDC 2016 - Animações no iOS

Globalcode – Open4education

Animações com AutoLayout

UIView Animation block

self.leftView.bounds = ... self.leftView.center = ...

O sistema seta os frames (Segundo layout)

Page 130: TDC 2016 - Animações no iOS

Globalcode – Open4education

Atualiza as constraints dentro do bloco

Mudar constraints

Page 131: TDC 2016 - Animações no iOS

Globalcode – Open4education

Atualiza as constraints dentro do bloco

Chama

Mudar constraints

[self.view layoutIfNeeded];

Page 132: TDC 2016 - Animações no iOS

Globalcode – Open4education

Atualiza as constraints dentro do bloco

Chama

Isso força um novo layout pass

Mudar constraints

[self.view layoutIfNeeded];

Page 133: TDC 2016 - Animações no iOS

Globalcode – Open4education

Atualiza as constraints dentro do bloco

Mudar constraints

[UIView animateWithDuration:0.5 animations:^{ self.leftConstraint.constant += 100;

}];[self.view layoutIfNeeded];

Page 134: TDC 2016 - Animações no iOS

Globalcode – Open4education

Atualiza as constraints dentro do bloco

Mudar constraints

[UIView animateWithDuration:0.5 animations:^{ self.leftConstraint.constant += 100;

}];[self.view layoutIfNeeded];

Page 135: TDC 2016 - Animações no iOS

Globalcode – Open4education

Agenda

Por que animações?

Debaixo dos panos com UIView animations

Problemas comuns e como resolvê-los

Novidades no iOS 10

Page 136: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

Nova arquitetura de animações

[UIView animateWithDuration: delay: options: animations:^{ } completion:^(BOOL finished) { }];

Métodos de classe

Page 137: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

Nova arquitetura de animações

@protocol UIViewAnimating <NSObject> @protocol UIViewImplicitlyAnimating <UIViewAnimating>

@protocol UITimingCurveProvider <NSCoding, NSCopying>

Protocolos

Page 138: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

Nova arquitetura de animações

UIViewPropertyAnimator

@protocol UIViewAnimating <NSObject> @protocol UIViewImplicitlyAnimating <UIViewAnimating>

@protocol UITimingCurveProvider <NSCoding, NSCopying>

Page 139: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

Nova arquitetura de animações

UITimingCurveProvider

@protocol UIViewAnimating <NSObject> @protocol UIViewImplicitlyAnimating <UIViewAnimating>

@protocol UITimingCurveProvider <NSCoding, NSCopying>

UIViewPropertyAnimator

Page 140: TDC 2016 - Animações no iOS

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

Page 141: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UITimingCurveProvider

@property(nonatomic, readonly) UITimingCurveType timingCurveType;

Page 142: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UITimingCurveProvider

@property(nonatomic, readonly) UITimingCurveType timingCurveType;

@property(nullable, nonatomic, readonly) UICubicTimingParameters *cubicTimingParameters; //Builtin, Cubic ou Composed

Page 143: TDC 2016 - Animações no iOS

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

Page 144: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

Page 145: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

- (void)pauseAnimation;

Page 146: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

- (void)pauseAnimation;- (void)finishAnimationAtPosition:(UIViewAnimatingPosition)finalPosition;

Page 147: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

- (void)pauseAnimation;- (void)finishAnimationAtPosition:(UIViewAnimatingPosition)finalPosition;

@property(nonatomic) CGFloat fractionComplete;

Page 148: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

- (void)pauseAnimation;- (void)finishAnimationAtPosition:(UIViewAnimatingPosition)finalPosition;

@property(nonatomic) CGFloat fractionComplete;

Útil para transições de View Controllers

Page 149: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

self.animator = [[UIViewPropertyAnimator alloc] initWithDuration:... curve:... animations:^{ ...

}];

Page 150: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

self.animator = [[UIViewPropertyAnimator alloc] initWithDuration:... curve:... animations:^{ ...

}];

[self.animator addAnimations:^{

} delayFactor:0.5];

Page 151: TDC 2016 - Animações no iOS

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.

Page 152: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

[self.animator pauseAnimation];

self.animator.fractionComplete = 0.5;

Page 153: TDC 2016 - Animações no iOS

Globalcode – Open4education

Novidades no iOS 10

UIViewPropertyAnimator

[self.animator continueAnimationWithTimingParameters:... durationFactor:0.5];

[self.animator pauseAnimation]; self.animator.fractionComplete = 0.5;

Page 154: TDC 2016 - Animações no iOS

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

Page 155: TDC 2016 - Animações no iOS

Globalcode – Open4education

Resumo

Page 156: TDC 2016 - Animações no iOS

Globalcode – Open4education

Resumo

Por que animações?

Page 157: TDC 2016 - Animações no iOS

Globalcode – Open4education

Resumo

Por que animações?

Debaixo dos panos com UIView animations

Page 158: TDC 2016 - Animações no iOS

Globalcode – Open4education

Resumo

Por que animações?

Debaixo dos panos com UIView animations

Problemas comuns e como resolvê-los

Page 159: TDC 2016 - Animações no iOS

Globalcode – Open4education

Resumo

Por que animações?

Debaixo dos panos com UIView animations

Problemas comuns e como resolvê-los

Novidades no iOS 10

Page 160: TDC 2016 - Animações no iOS

Globalcode – Open4education

Obrigado!