advanced ui styling and animations for ios

Post on 14-Apr-2017

429 Views

Category:

Engineering

4 Downloads

Preview:

Click to see full reader

TRANSCRIPT

© 2015 WIRE SWISS GMBH

Advanced UI styling and animations for iOS

© 2015 WIRE SWISS GMBH

Advanced UI styling and animations for iOS

© 2014 WIRE SWISS GMBH

About the Author: Mike Gerasymenko

• Working on iOS since 2008 (iOS 2.2)

• Around 35 apps for the AppStore

• With Wire since March 2014

© 2014 WIRE SWISS GMBH

Disclaimer

• A lot of open-source code is used

• Not all presented is created at Wire

• We love open-source and we do pull requests and share the things we develop

• github.com/wearezeta

© 2014 WIRE SWISS GMBH

Follow-Up on Cristobal’s presentation

• Why I brought up this topic?

• Bring the Sense of continuity

• Broaden-up the insight for those who was interested last time

• Give a deep insight on how UI works in Wire

• Design is crucial

© 2015 WIRE SWISS GMBH

Plan

• Everything is Custom:

• Custom animation’s timings on UIViews and CALayers

• Custom styling for the user interface

• One More Thing

© 2014 WIRE SWISS GMBH

Glossary

© 2014 WIRE SWISS GMBH

Animation timing (easing): functions

• Animation is a change of property from initial (A) to end value (B) in given time (t)

• How the change is distributed over the time t?

• Timing curve (Easing):

• Gives animation progress for time

• Implementation:

• UIView: predefined set of timing curves

• CoreAnimation: can be defined as arbitrary Bézier curve that starts in (0, 0) and ends in (1, 1), so two control points can vary

© 2014 WIRE SWISS GMBH

Animation timing (easing): functions

• Animation is a change of property from initial (A) to end value (B) in given time (t)

• How the change is distributed over the time t?

• Timing curve (Easing):

• Gives animation progress for time

• Implementation:

• UIView: predefined set of timing curves

• CoreAnimation: can be defined as arbitrary Bézier curve that starts in (0, 0) and ends in (1, 1), so two control points can vary

© 2014 WIRE SWISS GMBH

Animation timing (easing): example

© 2014 WIRE SWISS GMBH

Animation timing (easing): custom timing

Why custom timing function is important?Because designers says soBecause it looks better and makes the differenceHow we can use custom timing function with UIView animation?We can’t, it is not supported by the API

?

© 2015 WIRE SWISS GMBH

Animation timing (easing): Math 101

• Bezier curves are defined as power functions

• Exponential functions are the different set of functions

• Use «Best Fitting» Bezier curves, would be not equal to expo but close enough

• Root mean squared error is as low as 0.00000102( ) ( )( )( ) ( )( ) tttt dxxfy 1

1

0

2

∫ −

© 2014 WIRE SWISS GMBH

The Problem

© 2015 WIRE SWISS GMBH

Animation timing (easing)

• UIView animations do not support custom easing

• CoreAnimation API is complicated and bulky

• We need to implement the API that would work as UIView, but support passing in the custom easing

© 2015 WIRE SWISS GMBH

Animation timing (easing): UIView animation 101

• UIViews are using CALayers (.layer from CoreAnimation framework) to display it’s contents

• CALayers are using CAAnimation family to do animations

• Conclusion: when UIView animation is created the backing animation is CAAnimation anyway

• We need to find a way to create CAAnimations like iOS do: 1 [UIView animateWithDuration: timingFunction: animations:^{ 2 view.property = newValue; 3 }]

and produce the CAAnimations on the appropriate objects

© 2015 WIRE SWISS GMBH

Animation timing (easing): Introducing UIView+ExtendedBlockAnimations

• Approach:

• Swizzle -[CALayer actionForLayer:forKey:]

• When animation method is called, call UIView animation block with the same parameters and expect it to create the animations on CALayers

• Capture when UIView creates it’s animations

• Replace created animations with our own animations that are utilising the custom timing functions

© 2014 WIRE SWISS GMBH

To The Code

© 2015 WIRE SWISS GMBH

Animation timing (easing): Preparation

Swizzle: 1 SEL originalSelector = @selector(actionForLayer:forKey:); 2 SEL extendedSelector = @selector(WR_actionForLayer:forKey:); 3 4 Method originalMethod = class_getInstanceMethod(self, originalSelector); 5 Method extendedMethod = class_getInstanceMethod(self, extendedSelector); 6 7 method_exchangeImplementations(originalMethod, extendedMethod); Apply: 1 - (id<CAAction>)WR_actionForLayer:(CALayer *)layer forKey:(NSString *)event

2 { 3 ... 4 if (currentContext == BlockAnimationsContext && 5 [supportedProperties containsObject:event]) { 6 7 [savedAnimations addObject:[WRSavedAnimationState savedStateWithLayer:layer 8 keyPath:event]]; 9 10 // no implicit animation (it will be added later) 11 return (id<CAAction>)[NSNull null]; 12 } 13 ... 14 }

© 2015 WIRE SWISS GMBH

Animation timing (easing): application

1 + (void)wr_animateWithEasing:(RBBEasingFunction)easing 2 duration:(NSTimeInterval)duration 3 delay:(NSTimeInterval)delay 4 animations:(void (^)(void))animations 5 options:(WRExtendedBlockAnimationsOptions)options 6 completion:(void (^)(BOOL finished))completion 7 { 8 RBBTweenAnimation *animation = [[RBBTweenAnimation alloc] init]; // create the template anim 9 animation.easing = easing; 10 ... 11 12 [self wr_animateWithBasicAnimation:animation 13 duration:duration 14 animations:animations 15 options:options 16 completion:completion]; 17 }

© 2015 WIRE SWISS GMBH

Animation timing (easing): easy as 1-2-3

1 [UIView wr_animateWithEasing:RBBEasingFunctionEaseInExpo duration:0.35 delay:0 animations:^{ 2 // Do animations 3 view.frame = newFrame; 4 view.alpha = 1.0f; 5 view.transform = newTransform; 6 } completion:^(BOOL finished) { 7 // Do completion 8 }];

© 2014 WIRE SWISS GMBH

© 2014 WIRE SWISS GMBH

Animation timing (easing)

Grab it at goo.gl/uYItrG

© 2014 WIRE SWISS GMBH

Questions

© 2014 WIRE SWISS GMBH

Interface Styling

Defining User Interface style

© 2014 WIRE SWISS GMBH

Interface Styling: What we need?

• Ability to define UI element’s style:

• Colour

• Font

• Insets

• Any other style-related property

• Per element objc-class, class, parent

• Ability to tweak style during runtime

• Clean stylesheet format

© 2014 WIRE SWISS GMBH

Interface Styling: Classy!

✓ Ability to define UI element’s style:

✓ Colour

✓ Font

✓ Insets

✓ Any other style-related property

✓ Per element objc-class, class, parent

✓ Ability to tweak style during runtime

✓ Clean stylesheet format

© 2014 WIRE SWISS GMBH

– http://cloudkite.github.io/Classy/

“Not CSS. Instead of trying to force UIKit to fit CSS syntax, properties, conventions and constructs. Classy is a stylesheet system built from the ground up to work in harmony with UIKit. It borrows the best ideas from CSS and introduces new syntax, conventions and constructs where appropriate.”

Interface Styling: Classy!

© 2014 WIRE SWISS GMBH

Interface Styling: Classy integration

• Steps to integrate Classy:

• Grab framework via

• CocoaPods: pod 'Classy', '~> 0.2.4’

• Carthage: github "cloudkite/Classy"

• Create stylesheet

• Insert minimal initialisation code

• Profit!

© 2014 WIRE SWISS GMBH

Interface Styling: Classy stylesheet

1 @import "colors.cas"; 2 3 $accentColor = #acacac; 4 5 // Supports custom UIView subclasses 6 WireView { 7 background-color: $accentColor; 8 title-insets: 5, 10, 5, 10; 9 > UIProgressView.tinted { 10 progress-tint-color: rgb(200, 155, 110, 0.6); 11 track-tint-color: yellow; 12 } 13 } 14 15 ^UIButton.warning, UIView.warning ^UIButton { 16 title-color[state:highlighted]: #e3e3e3; 27 }

© 2014 WIRE SWISS GMBH

Interface Styling: Classy selectors

• Selectors:

• Runtime class name

• cas_styleClass class

• Containment

• Property of

• Selectors can be mixed

© 2014 WIRE SWISS GMBH

Interface Styling: Classy properties

• Properties supported:

• Any system or user-defined

• Property types supported:

• UIColor

• UIFont

• UIEdgeInsets

• Any custom property

© 2014 WIRE SWISS GMBH

Interface Styling: Classy in the nutshell

+ Classy =

Un-Styled UI

Different themes

or

© 2014 WIRE SWISS GMBH

Interface Styling: Classy testing

• Selectors and properties

• Covered by unit and integration tests

• We commit to Classy with PRs; adding more test coverage to the product

© 2014 WIRE SWISS GMBH

One more thing

© 2014 WIRE SWISS GMBH

Interface Styling: Classy live editing

• Classy can observe the filesystem changes on the stylesheet and re-apply the updates live

• Knowing that we added the WebDAV client in the application’s development builds

• Now design people can tweak certain properties realtime using the iPhone, dev build and their mac with a text editor

© 2014 WIRE SWISS GMBH

Questions

© 2014 WIRE SWISS GMBH

© 2014 WIRE SWISS GMBH

Regards to my fellow colleagues

Cristobal Castilla Jacob Persson

Vjacheslav Volodko

Alan Duric Marke Saaremets Natalia Dorozala

© 2014 WIRE SWISS GMBH

Contact data

Mike Gerasymenko

mihail@gerasimenko.me (find me on Wire using this email)

mike@wire.com

© 2014 WIRE SWISS GMBH

top related