hackatron - uikit dynamics

384
Renzo G. Pretto iOS Developer UIKit Dynamics Let the physics flow

Upload: renzo-pretto

Post on 15-Jan-2015

404 views

Category:

Technology


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Hackatron - UIKit Dynamics

Renzo G. PrettoiOS Developer

UIKit DynamicsLet the physics flow

Page 2: Hackatron - UIKit Dynamics

Who’s talking

Page 3: Hackatron - UIKit Dynamics

Who’s talking

Page 4: Hackatron - UIKit Dynamics

About me

Renzo iOS DeveloperH-art!

#pragma mark [email protected]!

@rgpretto

Page 5: Hackatron - UIKit Dynamics
Page 6: Hackatron - UIKit Dynamics

Chi siamoprogrammatori e imprenditori, ma soprattutto appassionati

Page 7: Hackatron - UIKit Dynamics

Cosacreare una community di sviluppatori iOS e OS X

Page 8: Hackatron - UIKit Dynamics

Perchésentivamo l’esigenza di condividere e confrontarci

Page 9: Hackatron - UIKit Dynamics

Dovenel mondo virtuale, ma soprattutto nel mondo reale

Page 10: Hackatron - UIKit Dynamics

Comeattraverso incontri periodici, eventi formativi e conferenze

Page 11: Hackatron - UIKit Dynamics

Associazionedal Settembre siamo ufficialmente un’associazione culturale

Page 12: Hackatron - UIKit Dynamics

Associazionedal Settembre siamo ufficialmente un’associazione culturale

Massimo

Giuseppe

RenzoMatteoFrancesco

Marco

Paolo

Stefano

Page 13: Hackatron - UIKit Dynamics

Statuto

Page 14: Hackatron - UIKit Dynamics

Statuto L’associazione senza fini di lucro #pragma mark ha lo

scopo di svolgere attività di “community of practice, ovvero di condivisione delle conoscenze ed esperienze tra persone

la cui professionalità ruota intorno le tecnologie informatiche e iOS in particolare, fornendo un nuovo

modello per connetterle nello spirito dell’apprendimento, della conoscenza condivisa e della collaborazione sia come

individui sia come gruppi”

Page 15: Hackatron - UIKit Dynamics
Page 16: Hackatron - UIKit Dynamics

152 partecipanti

16 speaker

15 sponsor

8 organizzatori

Page 17: Hackatron - UIKit Dynamics

16 sessioni tecniche

10 ore di conferenza

2 track tematiche

20 gadget, licenze e coupon

Page 18: Hackatron - UIKit Dynamics

Comunità

Page 19: Hackatron - UIKit Dynamics

Ottobre 2013la comunità è cresciuta molto, oggi siamo in 150

Page 20: Hackatron - UIKit Dynamics

Partecipantipiù di 300 persone hanno seguito i nostri eventi

Page 21: Hackatron - UIKit Dynamics

Social205 iscritti al gruppo su facebook e 122 follower su twitter

Page 22: Hackatron - UIKit Dynamics

Eventisvolti 9 eventi

Page 23: Hackatron - UIKit Dynamics

DoveBrescia, Bergamo, Verona, Venezia, Milano

e presto a Treviso e Roma

Page 24: Hackatron - UIKit Dynamics

follow us @pragmamarkorg

fb.com/groups/pragmamark/join to

subscribe on pragmamark.org

Page 25: Hackatron - UIKit Dynamics
Page 26: Hackatron - UIKit Dynamics

Today Agenda

• Introduction and core concepts

Page 27: Hackatron - UIKit Dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

Page 28: Hackatron - UIKit Dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

Page 29: Hackatron - UIKit Dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

•Advanced concepts

Page 30: Hackatron - UIKit Dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

•Advanced concepts

•UIDynamicItem

Page 31: Hackatron - UIKit Dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

•Advanced concepts

•UIDynamicItem

•Collection View

Page 32: Hackatron - UIKit Dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

•Advanced concepts

•UIDynamicItem

•Collection View

•Conclusion

Page 33: Hackatron - UIKit Dynamics

UIKit Dynamics

Page 34: Hackatron - UIKit Dynamics

UIKit Dynamics

Page 35: Hackatron - UIKit Dynamics

UIKit Dynamics

Page 36: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator

Page 37: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehaviorUIDynamicBehavior

Page 38: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehaviorUIDynamicBehavior

Page 39: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehavior

View

UIDynamicBehavior

Page 40: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehavior

View View

UIDynamicBehavior

Page 41: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehavior

View View View

UIDynamicBehavior

Page 42: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator Reference view

UIDynamicBehavior UIDynamicBehavior

View View View

UIDynamicBehavior

Page 43: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator Reference view

UIDynamicBehavior UIDynamicBehavior

View View View

UIDynamicBehavior

Page 44: Hackatron - UIKit Dynamics

UIDynamicAnimator

UIDynamicAnimator

Page 45: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate systemUIDynamicAnimator

Reference view

Page 46: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engineUIDynamicAnimator

Reference view

Page 47: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engine

•Keeps track of all the associated behaviors

UIDynamicAnimator

Reference view

Page 48: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engine

•Keeps track of all the associated behaviors

•Run and optimize the animation

UIDynamicAnimator

Reference view

Page 49: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engine

•Keeps track of all the associated behaviors

•Run and optimize the animation

•Each dynamic animator is independent from other dynamic animators

UIDynamicAnimator

Reference view

Page 50: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engine

•Keeps track of all the associated behaviors

•Run and optimize the animation

•Each dynamic animator is independent from other dynamic animators

UIDynamicAnimator *dynamicAnimator; !dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:referenceView]; !dynamicAnimator.delegate = self; ... ![dynamicAnimator addBehavior:firstBehavior]; [dynamicAnimator addBehavior:secondBehavior]; ...

UIDynamicAnimator

Reference view

Page 51: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engine

•Keeps track of all the associated behaviors

•Run and optimize the animation

•Each dynamic animator is independent from other dynamic animators

UIDynamicAnimator *dynamicAnimator; !dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:referenceView]; !dynamicAnimator.delegate = self; ... ![dynamicAnimator addBehavior:firstBehavior]; [dynamicAnimator addBehavior:secondBehavior]; ...

UIDynamicAnimator

Reference view

Page 52: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engine

•Keeps track of all the associated behaviors

•Run and optimize the animation

•Each dynamic animator is independent from other dynamic animators

UIDynamicAnimator *dynamicAnimator; !dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:referenceView]; !dynamicAnimator.delegate = self; ... ![dynamicAnimator addBehavior:firstBehavior]; [dynamicAnimator addBehavior:secondBehavior]; ...

UIDynamicAnimator

Reference view

Page 53: Hackatron - UIKit Dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engine

•Keeps track of all the associated behaviors

•Run and optimize the animation

•Each dynamic animator is independent from other dynamic animators

UIDynamicAnimator *dynamicAnimator; !dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:referenceView]; !dynamicAnimator.delegate = self; ... ![dynamicAnimator addBehavior:firstBehavior]; [dynamicAnimator addBehavior:secondBehavior]; ...

UIDynamicAnimator

Reference view

Page 54: Hackatron - UIKit Dynamics

UIDynamicAnimatorDelegate

@protocol UIDynamicAnimatorDelegate <NSObject> !@optional - (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; - (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; !@end

Page 55: Hackatron - UIKit Dynamics

UIDynamicAnimatorDelegate

•Notify pausing and resuming of UIKit Dynamic animator

@protocol UIDynamicAnimatorDelegate <NSObject> !@optional - (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; - (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; !@end

Page 56: Hackatron - UIKit Dynamics

UIDynamicBehaviour

UIDynamicBehavior

Page 57: Hackatron - UIKit Dynamics

UIDynamicBehaviour

•Associated to UIDynamicAnimator

UIDynamicAnimator

UIDynamicBehavior

Page 58: Hackatron - UIKit Dynamics

UIDynamicBehaviour

•Associated to UIDynamicAnimator•Add and remove behaviours to an animator at any times

UIDynamicAnimator

UIDynamicBehavior

Page 59: Hackatron - UIKit Dynamics

UIDynamicBehaviour

•Associated to UIDynamicAnimator•Add and remove behaviours to an animator at any times•Usually associated to a view or a set of view

UIDynamicAnimator

UIDynamicBehavior

View View

Page 60: Hackatron - UIKit Dynamics

UIDynamicBehaviour

•Associated to UIDynamicAnimator•Add and remove behaviours to an animator at any times•Usually associated to a view or a set of view•Composed

UIDynamicAnimator

UIDynamicBehavior

View View UIDynamicBehavior

View

Page 61: Hackatron - UIKit Dynamics

UIDynamicBehaviour

•Associated to UIDynamicAnimator•Add and remove behaviours to an animator at any times•Usually associated to a view or a set of view•Composed•Can be subclassed

UIDynamicAnimator

UIDynamicBehavior

View View UIDynamicBehavior

View

Page 62: Hackatron - UIKit Dynamics

Behaviors Common characteristics

• Initialised with items to animate

Page 63: Hackatron - UIKit Dynamics

Behaviors Common characteristics

• Initialised with items to animate

• Items can be added to behavior at any times

Page 64: Hackatron - UIKit Dynamics

Behaviors Common characteristics

• Initialised with items to animate

• Items can be added to behavior at any times

•Behaviour can be configured before or after add to an animator

Page 65: Hackatron - UIKit Dynamics

Behaviors Common characteristics

• Initialised with items to animate

• Items can be added to behavior at any times

•Behaviour can be configured before or after add to an animator

•Behavior influence stops when behaviour is removed

Page 66: Hackatron - UIKit Dynamics

Primitive behaviors

Page 67: Hackatron - UIKit Dynamics

Default Behaviors

UIDynamicBehavior

Page 68: Hackatron - UIKit Dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior•Gravity

Page 69: Hackatron - UIKit Dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior•Collisions

•Gravity

Page 70: Hackatron - UIKit Dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

•Collisions

•Gravity

•Attachments

Page 71: Hackatron - UIKit Dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

•Collisions

•Gravity

•Attachments

•Snap

Page 72: Hackatron - UIKit Dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

•Collisions

•Gravity

•Attachments

•Snap

•Forces

Page 73: Hackatron - UIKit Dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

•Collisions

•Gravity

•Attachments

•Snap

•Forces

• Item properties

Page 74: Hackatron - UIKit Dynamics

UIGravityBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 75: Hackatron - UIKit Dynamics

UIGravityBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 76: Hackatron - UIKit Dynamics

UIGravityBehavior

Page 77: Hackatron - UIKit Dynamics

@interface DPGravityViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end @implementation DPGravityViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UIGravityBehavior *gravityBehavior; gravityBehavior = [[UIGravityBehavior alloc] initWithItems:items]; ! [self.animator addBehavior:gravityBehavior]; !} ... @end

UIGravityBehavior

Page 78: Hackatron - UIKit Dynamics

@interface DPGravityViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end @implementation DPGravityViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UIGravityBehavior *gravityBehavior; gravityBehavior = [[UIGravityBehavior alloc] initWithItems:items]; ! [self.animator addBehavior:gravityBehavior]; !} ... @end

UIGravityBehavior

Page 79: Hackatron - UIKit Dynamics

@interface DPGravityViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end @implementation DPGravityViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UIGravityBehavior *gravityBehavior; gravityBehavior = [[UIGravityBehavior alloc] initWithItems:items]; ! [self.animator addBehavior:gravityBehavior]; !} ... @end

UIGravityBehavior

Page 80: Hackatron - UIKit Dynamics

@interface DPGravityViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end @implementation DPGravityViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UIGravityBehavior *gravityBehavior; gravityBehavior = [[UIGravityBehavior alloc] initWithItems:items]; ! [self.animator addBehavior:gravityBehavior]; !} ... @end

UIGravityBehavior

Page 81: Hackatron - UIKit Dynamics

@interface DPGravityViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end @implementation DPGravityViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UIGravityBehavior *gravityBehavior; gravityBehavior = [[UIGravityBehavior alloc] initWithItems:items]; ! [self.animator addBehavior:gravityBehavior]; !} ... @end

UIGravityBehavior

Page 82: Hackatron - UIKit Dynamics

UIGravityBehavior

•Defined by a gravity vector@property (readwrite, nonatomic) CGVector gravityDirection;

Page 83: Hackatron - UIKit Dynamics

UIGravityBehavior

•Defined by a gravity vector@property (readwrite, nonatomic) CGVector gravityDirection;

or@property (readwrite, nonatomic) CGFloat angle; @property (readwrite, nonatomic) CGFloat magnitude;

Page 84: Hackatron - UIKit Dynamics

UIGravityBehavior

•Defined by a gravity vector@property (readwrite, nonatomic) CGVector gravityDirection;

or@property (readwrite, nonatomic) CGFloat angle; @property (readwrite, nonatomic) CGFloat magnitude;

•Default vector is (0.0, 1.0)(0.0, 1.0)

Page 85: Hackatron - UIKit Dynamics

UIGravityBehavior

•Defined by a gravity vector@property (readwrite, nonatomic) CGVector gravityDirection;

or@property (readwrite, nonatomic) CGFloat angle; @property (readwrite, nonatomic) CGFloat magnitude;

•Default vector is (0.0, 1.0)

•Magnitude 1.0 accelerate view to 1000 points/s2 (0.0, 1.0)

Page 86: Hackatron - UIKit Dynamics

UIGravityBehavior

•Defined by a gravity vector@property (readwrite, nonatomic) CGVector gravityDirection;

or@property (readwrite, nonatomic) CGFloat angle; @property (readwrite, nonatomic) CGFloat magnitude;

•Default vector is (0.0, 1.0)

•Magnitude 1.0 accelerate view to 1000 points/s2

•Can add and remove items at any time

(0.0, 1.0)

- (void)addItem:(id <UIDynamicItem>)item; - (void)removeItem:(id <UIDynamicItem>)item;

Page 87: Hackatron - UIKit Dynamics

UICollisionBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 88: Hackatron - UIKit Dynamics

UICollisionBehavior

Page 89: Hackatron - UIKit Dynamics

UICollisionBehavior

@interface DPCollisionsViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPGravityCollisionViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UICollisionBehavior *collisionBehavior; collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items]; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; collisionBehavior.collisionDelegate = self; ! UIGravityBehavior *gravityBehavior; gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items]; [self.animator addBehavior:collisionBehavior]; [self.animator addBehavior:gravityBehavior]; } ... @end

Page 90: Hackatron - UIKit Dynamics

UICollisionBehavior

@interface DPCollisionsViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPGravityCollisionViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UICollisionBehavior *collisionBehavior; collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items]; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; collisionBehavior.collisionDelegate = self; ! UIGravityBehavior *gravityBehavior; gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items]; [self.animator addBehavior:collisionBehavior]; [self.animator addBehavior:gravityBehavior]; } ... @end

Page 91: Hackatron - UIKit Dynamics

UICollisionBehavior

@interface DPCollisionsViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPGravityCollisionViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UICollisionBehavior *collisionBehavior; collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items]; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; collisionBehavior.collisionDelegate = self; ! UIGravityBehavior *gravityBehavior; gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items]; [self.animator addBehavior:collisionBehavior]; [self.animator addBehavior:gravityBehavior]; } ... @end

Page 92: Hackatron - UIKit Dynamics

UICollisionBehavior

@interface DPCollisionsViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPGravityCollisionViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UICollisionBehavior *collisionBehavior; collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items]; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; collisionBehavior.collisionDelegate = self; ! UIGravityBehavior *gravityBehavior; gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items]; [self.animator addBehavior:collisionBehavior]; [self.animator addBehavior:gravityBehavior]; } ... @end

Page 93: Hackatron - UIKit Dynamics

UICollisionBehavior

@interface DPCollisionsViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPGravityCollisionViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UICollisionBehavior *collisionBehavior; collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items]; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; collisionBehavior.collisionDelegate = self; ! UIGravityBehavior *gravityBehavior; gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items]; [self.animator addBehavior:collisionBehavior]; [self.animator addBehavior:gravityBehavior]; } ... @end

Page 94: Hackatron - UIKit Dynamics

UICollisionBehavior

@interface DPCollisionsViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPGravityCollisionViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UICollisionBehavior *collisionBehavior; collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items]; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; collisionBehavior.collisionDelegate = self; ! UIGravityBehavior *gravityBehavior; gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items]; [self.animator addBehavior:collisionBehavior]; [self.animator addBehavior:gravityBehavior]; } ... @end

Page 95: Hackatron - UIKit Dynamics

UICollisionBehavior

@interface DPCollisionsViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPGravityCollisionViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; NSArray *items = @[self.greenView]; UICollisionBehavior *collisionBehavior; collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items]; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; collisionBehavior.collisionDelegate = self; ! UIGravityBehavior *gravityBehavior; gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items]; [self.animator addBehavior:collisionBehavior]; [self.animator addBehavior:gravityBehavior]; } ... @end

Page 96: Hackatron - UIKit Dynamics

Collision Boundaries

•Can specify different boundaries

Page 97: Hackatron - UIKit Dynamics

Collision Boundaries

•Can specify different boundaries•Reference view

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

Page 98: Hackatron - UIKit Dynamics

Collision Boundaries

•Can specify different boundaries•Reference view

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

• Insets to reference view- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;

Page 99: Hackatron - UIKit Dynamics

Collision Boundaries

•Can specify different boundaries•Reference view

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

• Insets to reference view- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;

•Segmentes- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;

Page 100: Hackatron - UIKit Dynamics

Collision Boundaries

•Can specify different boundaries•Reference view

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

• Insets to reference view- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;

•Segmentes- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;

•Bezier paths (approximated)- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath;

Page 101: Hackatron - UIKit Dynamics

Collision Boundaries

•Can specify different boundaries•Reference view

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

• Insets to reference view- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;

•Segmentes- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;

•Bezier paths (approximated)- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath;

Page 102: Hackatron - UIKit Dynamics

Collision Boundaries

•Can specify different boundaries•Reference view

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

• Insets to reference view- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;

•Segmentes- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;

•Bezier paths (approximated)- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath;

•Boundaries don't have an existence on screen

Page 103: Hackatron - UIKit Dynamics

Collision Mode

•Property collisionmode

Page 104: Hackatron - UIKit Dynamics

Collision Mode

•Property collisionmode@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

Page 105: Hackatron - UIKit Dynamics

Collision Mode

•Property collisionmode@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

• UICollisionBehaviorModeBoundaries

Page 106: Hackatron - UIKit Dynamics

Collision Mode

•Property collisionmode@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

• UICollisionBehaviorModeBoundaries• UICollisionBehaviorModeItems

Page 107: Hackatron - UIKit Dynamics

Collision Mode

•Property collisionmode@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

• UICollisionBehaviorModeBoundaries• UICollisionBehaviorModeItems

• UICollisionBehaviorModeEverything (default)

Page 108: Hackatron - UIKit Dynamics

Tips

•Can use multiple collision behaviors

Page 109: Hackatron - UIKit Dynamics

Tips

•Can use multiple collision behaviors

•Add and remove items to this behaviour anytime - (void)addItem:(id <UIDynamicItem>)item; - (void)removeItem:(id <UIDynamicItem>)item;

Page 110: Hackatron - UIKit Dynamics

Tips

•Can use multiple collision behaviors

•Add and remove items to this behaviour anytime

•Collision detection have CPU cost

- (void)addItem:(id <UIDynamicItem>)item; - (void)removeItem:(id <UIDynamicItem>)item;

Page 111: Hackatron - UIKit Dynamics

•Methods that inform collision start / end between view

UICollisionBehaviorDelegate

Page 112: Hackatron - UIKit Dynamics

•Methods that inform collision start / end between view- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;

UICollisionBehaviorDelegate

Page 113: Hackatron - UIKit Dynamics

•Methods that inform collision start / end between view- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;

•Methods that inform collision start /end between boundaries

UICollisionBehaviorDelegate

Page 114: Hackatron - UIKit Dynamics

•Methods that inform collision start / end between view- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;

•Methods that inform collision start /end between boundaries- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p;

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier;

UICollisionBehaviorDelegate

Page 115: Hackatron - UIKit Dynamics

•Methods that inform collision start / end between view- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;

•Methods that inform collision start /end between boundaries- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p;

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier;

UICollisionBehaviorDelegate

Page 116: Hackatron - UIKit Dynamics

•Methods that inform collision start / end between view- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;

•Methods that inform collision start /end between boundaries- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p;

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier;!•Reference view has nil identifier

UICollisionBehaviorDelegate

Page 117: Hackatron - UIKit Dynamics

UIAttachmentBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 118: Hackatron - UIKit Dynamics

UIAttachmentBehavior

Page 119: Hackatron - UIKit Dynamics

UIAttachmentBehavior@interface DPAttachmentViewController : UIViewController @property (weak, nonatomic) IBOutlet UIView *redView; @property (weak, nonatomic) IBOutlet UIView *greenView; @property (strong, nonatomic) UIDynamicAnimator *animator; @end !@implementation DPAttachmentViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; UIAttachmentBehavior *attachmentBehavior; attachmentBehavior =[[UIAttachmentBehavior alloc] initWithItem:self.greenView attachedToItem:self.redView]; [self.animator addBehavior:attachmentBehavior]; } !- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer { ! CGPoint anchorPoint = [gestureRecognizer locationInView:self.view]; self.redView.center = anchorPoint; [self.animator updateItemUsingCurrentState:self.redView]; } ... @end

Page 120: Hackatron - UIKit Dynamics

UIAttachmentBehavior@interface DPAttachmentViewController : UIViewController @property (weak, nonatomic) IBOutlet UIView *redView; @property (weak, nonatomic) IBOutlet UIView *greenView; @property (strong, nonatomic) UIDynamicAnimator *animator; @end !@implementation DPAttachmentViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; UIAttachmentBehavior *attachmentBehavior; attachmentBehavior =[[UIAttachmentBehavior alloc] initWithItem:self.greenView attachedToItem:self.redView]; [self.animator addBehavior:attachmentBehavior]; } !- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer { ! CGPoint anchorPoint = [gestureRecognizer locationInView:self.view]; self.redView.center = anchorPoint; [self.animator updateItemUsingCurrentState:self.redView]; } ... @end

Page 121: Hackatron - UIKit Dynamics

UIAttachmentBehavior@interface DPAttachmentViewController : UIViewController @property (weak, nonatomic) IBOutlet UIView *redView; @property (weak, nonatomic) IBOutlet UIView *greenView; @property (strong, nonatomic) UIDynamicAnimator *animator; @end !@implementation DPAttachmentViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; UIAttachmentBehavior *attachmentBehavior; attachmentBehavior =[[UIAttachmentBehavior alloc] initWithItem:self.greenView attachedToItem:self.redView]; [self.animator addBehavior:attachmentBehavior]; } !- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer { ! CGPoint anchorPoint = [gestureRecognizer locationInView:self.view]; self.redView.center = anchorPoint; [self.animator updateItemUsingCurrentState:self.redView]; } ... @end

Page 122: Hackatron - UIKit Dynamics

UIAttachmentBehavior@interface DPAttachmentViewController : UIViewController @property (weak, nonatomic) IBOutlet UIView *redView; @property (weak, nonatomic) IBOutlet UIView *greenView; @property (strong, nonatomic) UIDynamicAnimator *animator; @end !@implementation DPAttachmentViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; UIAttachmentBehavior *attachmentBehavior; attachmentBehavior =[[UIAttachmentBehavior alloc] initWithItem:self.greenView attachedToItem:self.redView]; [self.animator addBehavior:attachmentBehavior]; } !- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer { ! CGPoint anchorPoint = [gestureRecognizer locationInView:self.view]; self.redView.center = anchorPoint; [self.animator updateItemUsingCurrentState:self.redView]; } ... @end

Page 123: Hackatron - UIKit Dynamics

UIAttachmentBehavior@interface DPAttachmentViewController : UIViewController @property (weak, nonatomic) IBOutlet UIView *redView; @property (weak, nonatomic) IBOutlet UIView *greenView; @property (strong, nonatomic) UIDynamicAnimator *animator; @end !@implementation DPAttachmentViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; UIAttachmentBehavior *attachmentBehavior; attachmentBehavior =[[UIAttachmentBehavior alloc] initWithItem:self.greenView attachedToItem:self.redView]; [self.animator addBehavior:attachmentBehavior]; } !- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer { ! CGPoint anchorPoint = [gestureRecognizer locationInView:self.view]; self.redView.center = anchorPoint; [self.animator updateItemUsingCurrentState:self.redView]; } ... @end

Page 124: Hackatron - UIKit Dynamics

UIAttachmentBehavior@interface DPAttachmentViewController : UIViewController @property (weak, nonatomic) IBOutlet UIView *redView; @property (weak, nonatomic) IBOutlet UIView *greenView; @property (strong, nonatomic) UIDynamicAnimator *animator; @end !@implementation DPAttachmentViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; UIAttachmentBehavior *attachmentBehavior; attachmentBehavior =[[UIAttachmentBehavior alloc] initWithItem:self.greenView attachedToItem:self.redView]; [self.animator addBehavior:attachmentBehavior]; } !- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer { ! CGPoint anchorPoint = [gestureRecognizer locationInView:self.view]; self.redView.center = anchorPoint; [self.animator updateItemUsingCurrentState:self.redView]; } ... @end

Page 125: Hackatron - UIKit Dynamics

•View connected to an attachment point

UIAttachmentBehavior

Page 126: Hackatron - UIKit Dynamics

•View connected to an attachment point - (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)point;

UIAttachmentBehavior

Page 127: Hackatron - UIKit Dynamics

•View connected to an attachment point - (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)point;

•Two views connected together

UIAttachmentBehavior

Page 128: Hackatron - UIKit Dynamics

•View connected to an attachment point - (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)point;

•Two views connected together - (instancetype)initWithItem:(id <UIDynamicItem>)item1 attachedToItem:(id <UIDynamicItem>)item2;

UIAttachmentBehavior

Page 129: Hackatron - UIKit Dynamics

•View connected to an attachment point - (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)point;

•Two views connected together - (instancetype)initWithItem:(id <UIDynamicItem>)item1 attachedToItem:(id <UIDynamicItem>)item2;

•Specify connection point offset

UIAttachmentBehavior

Page 130: Hackatron - UIKit Dynamics

•View connected to an attachment point - (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)point;

•Two views connected together - (instancetype)initWithItem:(id <UIDynamicItem>)item1 attachedToItem:(id <UIDynamicItem>)item2;

•Specify connection point offset - (instancetype)initWithItem:(id <UIDynamicItem>)item offsetFromCenter:(UIOffset)offset attachedToAnchor:(CGPoint)point;

UIAttachmentBehavior

Page 131: Hackatron - UIKit Dynamics

•View connected to an attachment point - (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)point;

•Two views connected together - (instancetype)initWithItem:(id <UIDynamicItem>)item1 attachedToItem:(id <UIDynamicItem>)item2;

•Specify connection point offset - (instancetype)initWithItem:(id <UIDynamicItem>)item offsetFromCenter:(UIOffset)offset attachedToAnchor:(CGPoint)point;

- (instancetype)initWithItem:(id <UIDynamicItem>)item1 offsetFromCenter:(UIOffset)offset1 attachedToItem:(id <UIDynamicItem>)item2 offsetFromCenter:(UIOffset)offset2;

UIAttachmentBehavior

Page 132: Hackatron - UIKit Dynamics

Springs

•Springs

Page 133: Hackatron - UIKit Dynamics

Springs

•Springs @property (readwrite, nonatomic) CGFloat damping;

Page 134: Hackatron - UIKit Dynamics

Springs

•Springs @property (readwrite, nonatomic) CGFloat damping; @property (readwrite, nonatomic) CGFloat frequency;

Page 135: Hackatron - UIKit Dynamics

Springs

•Springs @property (readwrite, nonatomic) CGFloat damping; @property (readwrite, nonatomic) CGFloat frequency;

Page 136: Hackatron - UIKit Dynamics

UISnapBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 137: Hackatron - UIKit Dynamics

UISnapBehavior

Page 138: Hackatron - UIKit Dynamics

UISnapBehaviorinterface DPSnapViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPSnapViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; } !- (IBAction)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { ! CGPoint snapPoint = [gestureRecognizer locationInView:self.view]; if (nil != self.snapBehavior) { [self.dynamicAnimator removeBehavior:self.snapBehavior]; } self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.greenView snapToPoint:snapPoint]; [self.animator addBehavior:self.snapBehavior]; } ... @end

Page 139: Hackatron - UIKit Dynamics

UISnapBehaviorinterface DPSnapViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPSnapViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; } !- (IBAction)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { ! CGPoint snapPoint = [gestureRecognizer locationInView:self.view]; if (nil != self.snapBehavior) { [self.dynamicAnimator removeBehavior:self.snapBehavior]; } self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.greenView snapToPoint:snapPoint]; [self.animator addBehavior:self.snapBehavior]; } ... @end

Page 140: Hackatron - UIKit Dynamics

UISnapBehaviorinterface DPSnapViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPSnapViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; } !- (IBAction)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { ! CGPoint snapPoint = [gestureRecognizer locationInView:self.view]; if (nil != self.snapBehavior) { [self.dynamicAnimator removeBehavior:self.snapBehavior]; } self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.greenView snapToPoint:snapPoint]; [self.animator addBehavior:self.snapBehavior]; } ... @end

Page 141: Hackatron - UIKit Dynamics

UISnapBehaviorinterface DPSnapViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPSnapViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; } !- (IBAction)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { ! CGPoint snapPoint = [gestureRecognizer locationInView:self.view]; if (nil != self.snapBehavior) { [self.dynamicAnimator removeBehavior:self.snapBehavior]; } self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.greenView snapToPoint:snapPoint]; [self.animator addBehavior:self.snapBehavior]; } ... @end

Page 142: Hackatron - UIKit Dynamics

UISnapBehaviorinterface DPSnapViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPSnapViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; } !- (IBAction)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { ! CGPoint snapPoint = [gestureRecognizer locationInView:self.view]; if (nil != self.snapBehavior) { [self.dynamicAnimator removeBehavior:self.snapBehavior]; } self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.greenView snapToPoint:snapPoint]; [self.animator addBehavior:self.snapBehavior]; } ... @end

Page 143: Hackatron - UIKit Dynamics

UISnapBehaviorinterface DPSnapViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @property (weak, nonatomic) IBOutlet UIView *greenView; @end !@implementation DPSnapViewController ... - (void)viewDidLoad { [super viewDidLoad]; ! self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; } !- (IBAction)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { ! CGPoint snapPoint = [gestureRecognizer locationInView:self.view]; if (nil != self.snapBehavior) { [self.dynamicAnimator removeBehavior:self.snapBehavior]; } self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.greenView snapToPoint:snapPoint]; [self.animator addBehavior:self.snapBehavior]; } ... @end

Page 144: Hackatron - UIKit Dynamics

UISnapBehavior

•Snap view in place in non rotated state

Page 145: Hackatron - UIKit Dynamics

UISnapBehavior

•Snap view in place in non rotated state - (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;

Page 146: Hackatron - UIKit Dynamics

UISnapBehavior

•Snap view in place in non rotated state - (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;

•Customize the dumping effects

Page 147: Hackatron - UIKit Dynamics

UISnapBehavior

•Snap view in place in non rotated state - (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;

•Customize the dumping effects @property (nonatomic, assign) CGFloat damping;

Page 148: Hackatron - UIKit Dynamics

UIPushBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 149: Hackatron - UIKit Dynamics

UIPushBehavior

~F = m ~a

Page 150: Hackatron - UIKit Dynamics

UIPushBehavior

• , apply force to views: ~F = m ~a

Page 151: Hackatron - UIKit Dynamics

UIPushBehavior

• , apply force to views: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

~F = m ~a

Page 152: Hackatron - UIKit Dynamics

UIPushBehavior

• , apply force to views: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

•Force vector expressed in two way:

~F = m ~a

Page 153: Hackatron - UIKit Dynamics

UIPushBehavior

• , apply force to views: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

•Force vector expressed in two way: @property (readwrite, nonatomic) CGVector pushDirection;

~F = m ~a

Page 154: Hackatron - UIKit Dynamics

UIPushBehavior

• , apply force to views: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

•Force vector expressed in two way: @property (readwrite, nonatomic) CGVector pushDirection;

or @property (readwrite, nonatomic) CGFloat angle; @property (readwrite, nonatomic) CGFloat magnitude;

~F = m ~a

Page 155: Hackatron - UIKit Dynamics

UIPushBehavior

Page 156: Hackatron - UIKit Dynamics

UIPushBehavior

•Customize where apply this force in the view

Page 157: Hackatron - UIKit Dynamics

UIPushBehavior

•Customize where apply this force in the view

Page 158: Hackatron - UIKit Dynamics

UIPushBehavior

•Customize where apply this force in the view- (void)setTargetOffsetFromCenter:(UIOffset)o forItem:(id <UIDynamicItem>)item;

Page 159: Hackatron - UIKit Dynamics

UIPushBehavior

•Customize where apply this force in the view- (void)setTargetOffsetFromCenter:(UIOffset)o forItem:(id <UIDynamicItem>)item;

Page 160: Hackatron - UIKit Dynamics

UIPushBehavior

•Customize where apply this force in the view- (void)setTargetOffsetFromCenter:(UIOffset)o forItem:(id <UIDynamicItem>)item;

•Can add and remove items at any time

Page 161: Hackatron - UIKit Dynamics

UIPushBehavior

•Customize where apply this force in the view- (void)setTargetOffsetFromCenter:(UIOffset)o forItem:(id <UIDynamicItem>)item;

•Can add and remove items at any time- (void)addItem:(id <UIDynamicItem>)item; - (void)removeItem:(id <UIDynamicItem>)item;

Page 162: Hackatron - UIKit Dynamics

UIPushBehavior

•Customize where apply this force in the view- (void)setTargetOffsetFromCenter:(UIOffset)o forItem:(id <UIDynamicItem>)item;

•Can add and remove items at any time- (void)addItem:(id <UIDynamicItem>)item; - (void)removeItem:(id <UIDynamicItem>)item;

Page 163: Hackatron - UIKit Dynamics

UIPushBehavior

•Customize where apply this force in the view- (void)setTargetOffsetFromCenter:(UIOffset)o forItem:(id <UIDynamicItem>)item;

•Can add and remove items at any time- (void)addItem:(id <UIDynamicItem>)item; - (void)removeItem:(id <UIDynamicItem>)item;

Page 164: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

Page 165: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

• UIPushBehaviorModeContinuous

Page 166: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

Page 167: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

• views accelerate

Page 168: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

• views accelerate

•UIPushBehaviorModeInstantaneous

Page 169: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

• views accelerate

•UIPushBehaviorModeInstantaneous• apply a very quick impulse

Page 170: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

• views accelerate

•UIPushBehaviorModeInstantaneous• apply a very quick impulse

• view immediately acquire velocity (no acceleration)

Page 171: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

• views accelerate

•UIPushBehaviorModeInstantaneous• apply a very quick impulse

• view immediately acquire velocity (no acceleration)

• automatically disable itself after applying it

Page 172: Hackatron - UIKit Dynamics

UIPushBehavior Mode

•Different mode to apply forces: - (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

• views accelerate

•UIPushBehaviorModeInstantaneous• apply a very quick impulse

• view immediately acquire velocity (no acceleration)

• automatically disable itself after applying it

• to re-enable: @property (nonatomic, readwrite) BOOL active;

Page 173: Hackatron - UIKit Dynamics

Example: force comparison

~F = m ~a

~a =~F

m

Page 174: Hackatron - UIKit Dynamics

Example: force comparison

~F = m ~a

~a =~F

m

Page 175: Hackatron - UIKit Dynamics

Example: gravity comparison

Page 176: Hackatron - UIKit Dynamics

Feel The Force!

Page 177: Hackatron - UIKit Dynamics

Feel The Force!

•Gravity

Page 178: Hackatron - UIKit Dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

Page 179: Hackatron - UIKit Dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

•Push behavior in continuos mode

Page 180: Hackatron - UIKit Dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

•Push behavior in continuos mode

• the smaller views accelerate more

Page 181: Hackatron - UIKit Dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

•Push behavior in continuos mode

• the smaller views accelerate more

•Push behavior in instantaneous mode

Page 182: Hackatron - UIKit Dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

•Push behavior in continuos mode

• the smaller views accelerate more

•Push behavior in instantaneous mode

• view acquire velocity and then the velocity doesn’t change

Page 183: Hackatron - UIKit Dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

•Push behavior in continuos mode

• the smaller views accelerate more

•Push behavior in instantaneous mode

• view acquire velocity and then the velocity doesn’t change

• the smaller views acquire more velocity

Page 184: Hackatron - UIKit Dynamics

Unit of Measure

•Real world: Newton

Page 185: Hackatron - UIKit Dynamics

Unit of Measure

•Real world: Newton

• 1 Newton accelerate 1Kg at a rate of 1 m/s2

Page 186: Hackatron - UIKit Dynamics

Unit of Measure

•Real world: Newton

• 1 Newton accelerate 1Kg at a rate of 1 m/s2

•UIKit:

•  magnitude of 1.0 accelerate 100x100 point view to 100 points/s2

Page 187: Hackatron - UIKit Dynamics

Unit of Measure

•Real world: Newton

• 1 Newton accelerate 1Kg at a rate of 1 m/s2

•UIKit:

•  magnitude of 1.0 accelerate 100x100 point view to 100 points/s2

• “UIKit Newton”

Page 188: Hackatron - UIKit Dynamics

UIDynamicItemBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 189: Hackatron - UIKit Dynamics

•Customize dynamics properties for items

UIDynamicItemBehavior

Page 190: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity;

UIDynamicItemBehavior

Page 191: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction;

UIDynamicItemBehavior

Page 192: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density;

UIDynamicItemBehavior

Page 193: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density; @property (readwrite, nonatomic) CGFloat resistance;

UIDynamicItemBehavior

Page 194: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density; @property (readwrite, nonatomic) CGFloat resistance; @property (readwrite, nonatomic) CGFloat angularResistance;

UIDynamicItemBehavior

Page 195: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density; @property (readwrite, nonatomic) CGFloat resistance; @property (readwrite, nonatomic) CGFloat angularResistance; @property (readwrite, nonatomic) BOOL allowsRotation;

UIDynamicItemBehavior

Page 196: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density; @property (readwrite, nonatomic) CGFloat resistance; @property (readwrite, nonatomic) CGFloat angularResistance; @property (readwrite, nonatomic) BOOL allowsRotation;

•Add linear velocity (points per second)- (void)addLinearVelocity:(CGPoint)velocity forItem:(id <UIDynamicItem>)item;- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;

UIDynamicItemBehavior

Page 197: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density; @property (readwrite, nonatomic) CGFloat resistance; @property (readwrite, nonatomic) CGFloat angularResistance; @property (readwrite, nonatomic) BOOL allowsRotation;

•Add linear velocity (points per second)- (void)addLinearVelocity:(CGPoint)velocity forItem:(id <UIDynamicItem>)item;- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;

•Add angular velocity (radians per second) - (void)addAngularVelocity:(CGFloat)velocity forItem:(id <UIDynamicItem>)item; - (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;

UIDynamicItemBehavior

Page 198: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density; @property (readwrite, nonatomic) CGFloat resistance; @property (readwrite, nonatomic) CGFloat angularResistance; @property (readwrite, nonatomic) BOOL allowsRotation;

•Add linear velocity (points per second)- (void)addLinearVelocity:(CGPoint)velocity forItem:(id <UIDynamicItem>)item;- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;

•Add angular velocity (radians per second) - (void)addAngularVelocity:(CGFloat)velocity forItem:(id <UIDynamicItem>)item; - (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;

•Can add and remove items at any time

UIDynamicItemBehavior

Page 199: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density; @property (readwrite, nonatomic) CGFloat resistance; @property (readwrite, nonatomic) CGFloat angularResistance; @property (readwrite, nonatomic) BOOL allowsRotation;

•Add linear velocity (points per second)- (void)addLinearVelocity:(CGPoint)velocity forItem:(id <UIDynamicItem>)item;- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;

•Add angular velocity (radians per second) - (void)addAngularVelocity:(CGFloat)velocity forItem:(id <UIDynamicItem>)item; - (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;

•Can add and remove items at any time

UIDynamicItemBehavior

Page 200: Hackatron - UIKit Dynamics

•Customize dynamics properties for items @property (readwrite, nonatomic) CGFloat elasticity; @property (readwrite, nonatomic) CGFloat friction; @property (readwrite, nonatomic) CGFloat density; @property (readwrite, nonatomic) CGFloat resistance; @property (readwrite, nonatomic) CGFloat angularResistance; @property (readwrite, nonatomic) BOOL allowsRotation;

•Add linear velocity (points per second)- (void)addLinearVelocity:(CGPoint)velocity forItem:(id <UIDynamicItem>)item;- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;

•Add angular velocity (radians per second) - (void)addAngularVelocity:(CGFloat)velocity forItem:(id <UIDynamicItem>)item; - (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;

•Can add and remove items at any time

UIDynamicItemBehavior

Page 201: Hackatron - UIKit Dynamics

Long Story Short

• Identify the type of dynamic items you want to animate

Page 202: Hackatron - UIKit Dynamics

Long Story Short

• Identify the type of dynamic items you want to animate

•Define container or reference view

Page 203: Hackatron - UIKit Dynamics

Long Story Short

• Identify the type of dynamic items you want to animate

•Define container or reference view

•Create the behaviours

Page 204: Hackatron - UIKit Dynamics

Long Story Short

• Identify the type of dynamic items you want to animate

•Define container or reference view

•Create the behaviours

•Add items to behaviours

Page 205: Hackatron - UIKit Dynamics

Long Story Short

• Identify the type of dynamic items you want to animate

•Define container or reference view

•Create the behaviours

•Add items to behaviours

•Configure, add or remove behaviors to an animator

Page 206: Hackatron - UIKit Dynamics

Custom behaviors

Page 207: Hackatron - UIKit Dynamics

Custom Behavior

•Can subclass UIDynamicBehavior

Page 208: Hackatron - UIKit Dynamics

Custom Behavior

•Can subclass UIDynamicBehavior

• add child behavior - (void)addChildBehavior:(UIDynamicBehavior *)behavior; - (void)removeChildBehavior:(UIDynamicBehavior *)behavior;

@property (nonatomic, readonly, copy) NSArray* childBehaviors;

Page 209: Hackatron - UIKit Dynamics

Custom Behavior

•Can subclass UIDynamicBehavior

• add child behavior - (void)addChildBehavior:(UIDynamicBehavior *)behavior; - (void)removeChildBehavior:(UIDynamicBehavior *)behavior;

@property (nonatomic, readonly, copy) NSArray* childBehaviors;

•No CPU cost or any runtime difference

Page 210: Hackatron - UIKit Dynamics

Example: gravity & collision

Page 211: Hackatron - UIKit Dynamics

Example: gravity & collision@interface DPGravityCollisionViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @end !!@implementation DPGravityCollisionViewController !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; self.animator.delegate = self; NSArray *items = @[...]; UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items]; UICollisionBehavior *coll = [[UICollisionBehavior alloc] initWithItems:items]; coll.translatesReferenceBoundsIntoBoundary = YES; ! [self.animator addBehavior:gravity]; [self.animator addBehavior:coll]; } !@end

Page 212: Hackatron - UIKit Dynamics

Example: gravity & collision@interface DPGravityCollisionViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @end !!@implementation DPGravityCollisionViewController !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; self.animator.delegate = self; NSArray *items = @[...]; UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items]; UICollisionBehavior *coll = [[UICollisionBehavior alloc] initWithItems:items]; coll.translatesReferenceBoundsIntoBoundary = YES; ! [self.animator addBehavior:gravity]; [self.animator addBehavior:coll]; } !@end

Page 213: Hackatron - UIKit Dynamics

Example: gravity & collision@interface DPGravityCollisionViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @end !!@implementation DPGravityCollisionViewController !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; self.animator.delegate = self; NSArray *items = @[...]; UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items]; UICollisionBehavior *coll = [[UICollisionBehavior alloc] initWithItems:items]; coll.translatesReferenceBoundsIntoBoundary = YES; ! [self.animator addBehavior:gravity]; [self.animator addBehavior:coll]; } !@end

Page 214: Hackatron - UIKit Dynamics

Example: gravity & collision@interface DPGravityCollisionViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @end !!@implementation DPGravityCollisionViewController !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; self.animator.delegate = self; NSArray *items = @[...]; UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items]; UICollisionBehavior *coll = [[UICollisionBehavior alloc] initWithItems:items]; coll.translatesReferenceBoundsIntoBoundary = YES; ! [self.animator addBehavior:gravity]; [self.animator addBehavior:coll]; } !@end

Page 215: Hackatron - UIKit Dynamics

Example: gravity & collision@interface DPGravityCollisionViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @end !!@implementation DPGravityCollisionViewController !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; self.animator.delegate = self; NSArray *items = @[...]; UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items]; UICollisionBehavior *coll = [[UICollisionBehavior alloc] initWithItems:items]; coll.translatesReferenceBoundsIntoBoundary = YES; ! [self.animator addBehavior:gravity]; [self.animator addBehavior:coll]; } !@end

Page 216: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 217: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 218: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 219: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 220: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 221: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 222: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 223: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 224: Hackatron - UIKit Dynamics

@interface DPGravityCollisionBehavior : UIDynamicBehavior - (instancetype)initWithItems:(NSArray *)items; @end !!@implementation DPGravityCollisionBehavior !- (instancetype)initWithItems:(NSArray *)items { self = [super init]; if (self) { UIGravityBehavior *gravity; UICollisionBehavior *collision; ! gravity =[[UIGravityBehavior alloc] initWithItems:items]; collision = [[UICollisionBehavior alloc] initWithItems:items]; collision.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:gravity]; [self addChildBehavior:collision]; ! } return self; } !@end

Example: gravity & collision

Page 225: Hackatron - UIKit Dynamics

Example: gravity & collision@interface DPGravityCollisionViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @end !!@implementation DPGravityCollisionViewController !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; self.animator.delegate = self; NSArray *items = @[...]; !!!!!! ! } !@end

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items]; UICollisionBehavior *coll = [[UICollisionBehavior alloc] initWithItems:items]; coll.translatesReferenceBoundsIntoBoundary = YES; ! [self.animator addBehavior:gravity]; [self.animator addBehavior:coll];

Page 226: Hackatron - UIKit Dynamics

Example: gravity & collision@interface DPGravityCollisionViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator *animator; @end !!@implementation DPGravityCollisionViewController !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; self.animator.delegate = self; NSArray *items = @[...]; !!!!!! ! } !@end

DPGravityCollisionBehavior *gravityAndCollision; gravityAndCollision= [[DPGravityCollisionBehavior alloc] initWithItems:items]; ! [self.animator addBehavior:gravityAndCollision];

Page 227: Hackatron - UIKit Dynamics

Action Block

•Can define per-step actions

Page 228: Hackatron - UIKit Dynamics

Action Block

•Can define per-step actions @property (nonatomic, copy) void (^action)(void);

Page 229: Hackatron - UIKit Dynamics

Action Block

•Can define per-step actions @property (nonatomic, copy) void (^action)(void);

• UIDynamicAnimator invoke this block in each simulation step

Page 230: Hackatron - UIKit Dynamics

Action Block

•Can define per-step actions @property (nonatomic, copy) void (^action)(void);

• UIDynamicAnimator invoke this block in each simulation step

•So performance are crucial

Page 231: Hackatron - UIKit Dynamics

UIDynamicItem protocol

Page 232: Hackatron - UIKit Dynamics

UIDynamicItem Protocol@protocol UIDynamicItem <NSObject> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end

Page 233: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol

@protocol UIDynamicItem <NSObject> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end

Page 234: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol

•Describe what UIKit Dynamics needs to animate an item

@protocol UIDynamicItem <NSObject> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end

Page 235: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol

•Describe what UIKit Dynamics needs to animate an item

•position: center

@protocol UIDynamicItem <NSObject> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end

Page 236: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol

•Describe what UIKit Dynamics needs to animate an item

•position: center

• size: bounds

@protocol UIDynamicItem <NSObject> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end

Page 237: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol

•Describe what UIKit Dynamics needs to animate an item

•position: center

• size: bounds

• angle: transform (only 2D-transform)

@protocol UIDynamicItem <NSObject> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end

Page 238: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

• center, bounds, and transform are read only once by UIKit

Page 239: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

• center, bounds, and transform are read only once by UIKit • When adding the item to an animator for the first time

Page 240: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

• center, bounds, and transform are read only once by UIKit • When adding the item to an animator for the first time

• center and transform are set on every animation tick

Page 241: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

• center, bounds, and transform are read only once by UIKit • When adding the item to an animator for the first time

• center and transform are set on every animation tick • methods performances are critical

Page 242: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

• center, bounds, and transform are read only once by UIKit • When adding the item to an animator for the first time

• center and transform are set on every animation tick • methods performances are critical

•After grab the initial state every external change to center, bounds, and transform will be ignored

Page 243: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

• center, bounds, and transform are read only once by UIKit • When adding the item to an animator for the first time

• center and transform are set on every animation tick • methods performances are critical

•After grab the initial state every external change to center, bounds, and transform will be ignored

•A dynamic item should always have a valid initial state

Page 244: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

• center, bounds, and transform are read only once by UIKit • When adding the item to an animator for the first time

• center and transform are set on every animation tick • methods performances are critical

•After grab the initial state every external change to center, bounds, and transform will be ignored

•A dynamic item should always have a valid initial state• need a size

Page 245: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

• center, bounds, and transform are read only once by UIKit • When adding the item to an animator for the first time

• center and transform are set on every animation tick • methods performances are critical

•After grab the initial state every external change to center, bounds, and transform will be ignored

•A dynamic item should always have a valid initial state• need a size

• need a reasonable position

Page 246: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol

Page 247: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol • UIView conforms to protocol@interface UIView : UIResponder < NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem > { ... }

Page 248: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol • UIView conforms to protocol@interface UIView : UIResponder < NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem > { ... }

• UICollectionViewLayoutAttributes conforms to protocol@interface UICollectionViewLayoutAttributes : NSObject < NSCopying, UIDynamicItem > { ... }

Page 249: Hackatron - UIKit Dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol • UIView conforms to protocol@interface UIView : UIResponder < NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem > { ... }

• UICollectionViewLayoutAttributes conforms to protocol@interface UICollectionViewLayoutAttributes : NSObject < NSCopying, UIDynamicItem > { ... }

•Custom class can conform to protocol@interface DPDynamicObject : NSObject < UIDynamicItem > { ... }

Page 250: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator Reference view

UIDynamicBehavior UIDynamicBehavior

View View View

UIDynamicBehavior

Page 251: Hackatron - UIKit Dynamics

Architecture

UIDynamicAnimator Reference view

UIDynamicBehavior UIDynamicBehaviorUIDynamicBehavior

NSObject"<UIDynamicItem>

NSObject"<UIDynamicItem>

NSObject"<UIDynamicItem>

Page 252: Hackatron - UIKit Dynamics

@interface DPDynamicObject : NSObject <UIDynamicItem> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end !!@implementation DPDynamicObject !- (CGRect)bounds { return CGRectMake(0.0, 0.0, 100.0, 100.0); } !- (CGPoint)center { return CGPointMake(50.0, 50.0); } !- (void)setCenter:(CGPoint)center { NSLog(@"Center = %@", NSStringFromCGPoint(center)); } !- (CGAffineTransform)transform { return CGAffineTransformIdentity; } !- (void)setTransform:(CGAffineTransform)transform { NSLog(@"Transform = %@", NSStringFromCGAffineTransform(transform)); } !@end

Example 1: conform to UIDynamicItem

Page 253: Hackatron - UIKit Dynamics

@interface DPDynamicObject : NSObject <UIDynamicItem> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end !!@implementation DPDynamicObject !- (CGRect)bounds { return CGRectMake(0.0, 0.0, 100.0, 100.0); } !- (CGPoint)center { return CGPointMake(50.0, 50.0); } !- (void)setCenter:(CGPoint)center { NSLog(@"Center = %@", NSStringFromCGPoint(center)); } !- (CGAffineTransform)transform { return CGAffineTransformIdentity; } !- (void)setTransform:(CGAffineTransform)transform { NSLog(@"Transform = %@", NSStringFromCGAffineTransform(transform)); } !@end

Example 1: conform to UIDynamicItem

Page 254: Hackatron - UIKit Dynamics

@interface DPDynamicObject : NSObject <UIDynamicItem> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end !!@implementation DPDynamicObject !- (CGRect)bounds { return CGRectMake(0.0, 0.0, 100.0, 100.0); } !- (CGPoint)center { return CGPointMake(50.0, 50.0); } !- (void)setCenter:(CGPoint)center { NSLog(@"Center = %@", NSStringFromCGPoint(center)); } !- (CGAffineTransform)transform { return CGAffineTransformIdentity; } !- (void)setTransform:(CGAffineTransform)transform { NSLog(@"Transform = %@", NSStringFromCGAffineTransform(transform)); } !@end

Example 1: conform to UIDynamicItem

Page 255: Hackatron - UIKit Dynamics

@interface DPDynamicObject : NSObject <UIDynamicItem> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end !!@implementation DPDynamicObject !- (CGRect)bounds { return CGRectMake(0.0, 0.0, 100.0, 100.0); } !- (CGPoint)center { return CGPointMake(50.0, 50.0); } !- (void)setCenter:(CGPoint)center { NSLog(@"Center = %@", NSStringFromCGPoint(center)); } !- (CGAffineTransform)transform { return CGAffineTransformIdentity; } !- (void)setTransform:(CGAffineTransform)transform { NSLog(@"Transform = %@", NSStringFromCGAffineTransform(transform)); } !@end

Example 1: conform to UIDynamicItem

Page 256: Hackatron - UIKit Dynamics

@interface DPDynamicObject : NSObject <UIDynamicItem> !@property (nonatomic, readwrite) CGPoint center; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readwrite) CGAffineTransform transform; !@end !!@implementation DPDynamicObject !- (CGRect)bounds { return CGRectMake(0.0, 0.0, 100.0, 100.0); } !- (CGPoint)center { return CGPointMake(50.0, 50.0); } !- (void)setCenter:(CGPoint)center { NSLog(@"Center = %@", NSStringFromCGPoint(center)); } !- (CGAffineTransform)transform { return CGAffineTransformIdentity; } !- (void)setTransform:(CGAffineTransform)transform { NSLog(@"Transform = %@", NSStringFromCGAffineTransform(transform)); } !@end

Example 1: conform to UIDynamicItem

Page 257: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem@interface DPDynamicItemProtocolViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @property (strong, nonatomic) DPDynamicObject *dynamicObject; @end !@implementation DPDynamicItemProtocolViewController ... !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; ! self.dynamicObject = [[DPDynamicObject alloc] init]; ! UIGravityBehavior *g; g =[[UIGravityBehavior alloc] initWithItems: @[self.dynamicObject] ]; UIDynamicItemBehavior *b; b =[[UIDynamicItemBehavior alloc] initWithItems: @[self.dynamicObject] ]; b.elasticity = 0.5f; UICollisionBehavior *c; c =[[UICollisionBehavior alloc] initWithItems: @[self.dynamicObject] ]; c.translatesReferenceBoundsIntoBoundary = YES; [self.animator addBehavior:g]; [self.animator addBehavior:b]; [self.animator addBehavior:c]; } ... @end

Page 258: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem@interface DPDynamicItemProtocolViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @property (strong, nonatomic) DPDynamicObject *dynamicObject; @end !@implementation DPDynamicItemProtocolViewController ... !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; ! self.dynamicObject = [[DPDynamicObject alloc] init]; ! UIGravityBehavior *g; g =[[UIGravityBehavior alloc] initWithItems: @[self.dynamicObject] ]; UIDynamicItemBehavior *b; b =[[UIDynamicItemBehavior alloc] initWithItems: @[self.dynamicObject] ]; b.elasticity = 0.5f; UICollisionBehavior *c; c =[[UICollisionBehavior alloc] initWithItems: @[self.dynamicObject] ]; c.translatesReferenceBoundsIntoBoundary = YES; [self.animator addBehavior:g]; [self.animator addBehavior:b]; [self.animator addBehavior:c]; } ... @end

Page 259: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem@interface DPDynamicItemProtocolViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @property (strong, nonatomic) DPDynamicObject *dynamicObject; @end !@implementation DPDynamicItemProtocolViewController ... !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; ! self.dynamicObject = [[DPDynamicObject alloc] init]; ! UIGravityBehavior *g; g =[[UIGravityBehavior alloc] initWithItems: @[self.dynamicObject] ]; UIDynamicItemBehavior *b; b =[[UIDynamicItemBehavior alloc] initWithItems: @[self.dynamicObject] ]; b.elasticity = 0.5f; UICollisionBehavior *c; c =[[UICollisionBehavior alloc] initWithItems: @[self.dynamicObject] ]; c.translatesReferenceBoundsIntoBoundary = YES; [self.animator addBehavior:g]; [self.animator addBehavior:b]; [self.animator addBehavior:c]; } ... @end

Page 260: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem@interface DPDynamicItemProtocolViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @property (strong, nonatomic) DPDynamicObject *dynamicObject; @end !@implementation DPDynamicItemProtocolViewController ... !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; ! self.dynamicObject = [[DPDynamicObject alloc] init]; ! UIGravityBehavior *g; g =[[UIGravityBehavior alloc] initWithItems: @[self.dynamicObject] ]; UIDynamicItemBehavior *b; b =[[UIDynamicItemBehavior alloc] initWithItems: @[self.dynamicObject] ]; b.elasticity = 0.5f; UICollisionBehavior *c; c =[[UICollisionBehavior alloc] initWithItems: @[self.dynamicObject] ]; c.translatesReferenceBoundsIntoBoundary = YES; [self.animator addBehavior:g]; [self.animator addBehavior:b]; [self.animator addBehavior:c]; } ... @end

Page 261: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem@interface DPDynamicItemProtocolViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @property (strong, nonatomic) DPDynamicObject *dynamicObject; @end !@implementation DPDynamicItemProtocolViewController ... !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; ! self.dynamicObject = [[DPDynamicObject alloc] init]; ! UIGravityBehavior *g; g =[[UIGravityBehavior alloc] initWithItems: @[self.dynamicObject] ]; UIDynamicItemBehavior *b; b =[[UIDynamicItemBehavior alloc] initWithItems: @[self.dynamicObject] ]; b.elasticity = 0.5f; UICollisionBehavior *c; c =[[UICollisionBehavior alloc] initWithItems: @[self.dynamicObject] ]; c.translatesReferenceBoundsIntoBoundary = YES; [self.animator addBehavior:g]; [self.animator addBehavior:b]; [self.animator addBehavior:c]; } ... @end

Page 262: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem@interface DPDynamicItemProtocolViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @property (strong, nonatomic) DPDynamicObject *dynamicObject; @end !@implementation DPDynamicItemProtocolViewController ... !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; ! self.dynamicObject = [[DPDynamicObject alloc] init]; ! UIGravityBehavior *g; g =[[UIGravityBehavior alloc] initWithItems: @[self.dynamicObject] ]; UIDynamicItemBehavior *b; b =[[UIDynamicItemBehavior alloc] initWithItems: @[self.dynamicObject] ]; b.elasticity = 0.5f; UICollisionBehavior *c; c =[[UICollisionBehavior alloc] initWithItems: @[self.dynamicObject] ]; c.translatesReferenceBoundsIntoBoundary = YES; [self.animator addBehavior:g]; [self.animator addBehavior:b]; [self.animator addBehavior:c]; } ... @end

Page 263: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem@interface DPDynamicItemProtocolViewController : UIViewController @property (strong, nonatomic) UIDynamicAnimator * animator; @property (strong, nonatomic) DPDynamicObject *dynamicObject; @end !@implementation DPDynamicItemProtocolViewController ... !- (void)viewDidLoad { [super viewDidLoad]; self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; ! self.dynamicObject = [[DPDynamicObject alloc] init]; ! UIGravityBehavior *g; g =[[UIGravityBehavior alloc] initWithItems: @[self.dynamicObject] ]; UIDynamicItemBehavior *b; b =[[UIDynamicItemBehavior alloc] initWithItems: @[self.dynamicObject] ]; b.elasticity = 0.5f; UICollisionBehavior *c; c =[[UICollisionBehavior alloc] initWithItems: @[self.dynamicObject] ]; c.translatesReferenceBoundsIntoBoundary = YES; [self.animator addBehavior:g]; [self.animator addBehavior:b]; [self.animator addBehavior:c]; } ... @end

Page 264: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem

Page 265: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem

2013-10-17 18:58:05.598 DynamicsPlayground[771:60b] Animator is running 2013-10-17 18:58:05.609 DynamicsPlayground[771:60b] Center = {50, 50.04797} 2013-10-17 18:58:05.611 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:05.626 DynamicsPlayground[771:60b] Center = {50, 50.447464} 2013-10-17 18:58:05.629 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:05.642 DynamicsPlayground[771:60b] Center = {50, 51.054173} 2013-10-17 18:58:05.645 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:05.659 DynamicsPlayground[771:60b] Center = {50, 51.915657} 2013-10-17 18:58:05.661 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:05.675 DynamicsPlayground[771:60b] Center = {50, 53.031506} 2013-10-17 18:58:05.677 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] !... !2013-10-17 18:58:08.742 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.744 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.759 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.761 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.775 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.777 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.792 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.794 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.809 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.810 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.812 DynamicsPlayground[771:60b] Animator is stopped

Page 266: Hackatron - UIKit Dynamics

Example 1: conform to UIDynamicItem

2013-10-17 18:58:05.598 DynamicsPlayground[771:60b] Animator is running 2013-10-17 18:58:05.609 DynamicsPlayground[771:60b] Center = {50, 50.04797} 2013-10-17 18:58:05.611 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:05.626 DynamicsPlayground[771:60b] Center = {50, 50.447464} 2013-10-17 18:58:05.629 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:05.642 DynamicsPlayground[771:60b] Center = {50, 51.054173} 2013-10-17 18:58:05.645 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:05.659 DynamicsPlayground[771:60b] Center = {50, 51.915657} 2013-10-17 18:58:05.661 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:05.675 DynamicsPlayground[771:60b] Center = {50, 53.031506} 2013-10-17 18:58:05.677 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] !... !2013-10-17 18:58:08.742 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.744 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.759 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.761 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.775 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.777 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.792 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.794 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.809 DynamicsPlayground[771:60b] Center = {50, 518.13135} 2013-10-17 18:58:08.810 DynamicsPlayground[771:60b] Transform = [1, 0, -0, 1, 0, 0] 2013-10-17 18:58:08.812 DynamicsPlayground[771:60b] Animator is stopped

Page 267: Hackatron - UIKit Dynamics

•Can use a single dynamic item to animate different views

UIDynamicItem Use Case

Page 268: Hackatron - UIKit Dynamics

•Can use a single dynamic item to animate different views

•Can map center or transform to something else

UIDynamicItem Use Case

Page 269: Hackatron - UIKit Dynamics

•Can use a single dynamic item to animate different views

•Can map center or transform to something else

•To “animate” something that isnt’a a view or a collection view use a UIDynamicItem

UIDynamicItem Use Case

Page 270: Hackatron - UIKit Dynamics

•Can use a single dynamic item to animate different views

•Can map center or transform to something else

•To “animate” something that isnt’a a view or a collection view use a UIDynamicItem

UIDynamicItem Use Case

Page 271: Hackatron - UIKit Dynamics

Example 2: remap center property

Page 272: Hackatron - UIKit Dynamics

Example 2: remap center property

@protocol ResizableDynamicItem <UIDynamicItem> !!@interface APLPositionToBoundsMapping : NSObject <UIDynamicItem> !- (instancetype)initWithTarget:(id<ResizableDynamicItem>)target; !@end !!@protocol ResizableDynamicItem <UIDynamicItem> !@property (nonatomic, readwrite) CGRect bounds; !@end

Page 273: Hackatron - UIKit Dynamics

Example 2: remap center property

@protocol ResizableDynamicItem <UIDynamicItem> !!@interface APLPositionToBoundsMapping : NSObject <UIDynamicItem> !- (instancetype)initWithTarget:(id<ResizableDynamicItem>)target; !@end !!@protocol ResizableDynamicItem <UIDynamicItem> !@property (nonatomic, readwrite) CGRect bounds; !@end

Page 274: Hackatron - UIKit Dynamics

Example 2: remap center property

@protocol ResizableDynamicItem <UIDynamicItem> !!@interface APLPositionToBoundsMapping : NSObject <UIDynamicItem> !- (instancetype)initWithTarget:(id<ResizableDynamicItem>)target; !@end !!@protocol ResizableDynamicItem <UIDynamicItem> !@property (nonatomic, readwrite) CGRect bounds; !@end

Page 275: Hackatron - UIKit Dynamics

Example 2: remap center property#import "APLPositionToBoundsMapping.h" !@interface APLPositionToBoundsMapping () @property (nonatomic, strong) id<ResizableDynamicItem> target; @end !@implementation APLPositionToBoundsMapping !- (instancetype)initWithTarget:(id<ResizableDynamicItem>)target { if ((self = [super init])) { _target = target; } return self; } !- (CGRect)bounds { return self.target.bounds; // Pass through } !- (CGPoint)center { return CGPointMake(self.target.bounds.size.width, self.target.bounds.size.height); } !- (void)setCenter:(CGPoint)center { self.target.bounds = CGRectMake(0, 0, center.x, center.y); } !- (CGAffineTransform)transform { return self.target.transform; // Pass through } !- (void)setTransform:(CGAffineTransform)transform { self.target.transform = transform; // Pass through } @end

Page 276: Hackatron - UIKit Dynamics

Example 2: remap center property#import "APLPositionToBoundsMapping.h" !@interface APLPositionToBoundsMapping () @property (nonatomic, strong) id<ResizableDynamicItem> target; @end !@implementation APLPositionToBoundsMapping !- (instancetype)initWithTarget:(id<ResizableDynamicItem>)target { if ((self = [super init])) { _target = target; } return self; } !- (CGRect)bounds { return self.target.bounds; // Pass through } !- (CGPoint)center { return CGPointMake(self.target.bounds.size.width, self.target.bounds.size.height); } !- (void)setCenter:(CGPoint)center { self.target.bounds = CGRectMake(0, 0, center.x, center.y); } !- (CGAffineTransform)transform { return self.target.transform; // Pass through } !- (void)setTransform:(CGAffineTransform)transform { self.target.transform = transform; // Pass through } @end

Page 277: Hackatron - UIKit Dynamics

Example 2: remap center property#import "APLPositionToBoundsMapping.h" !@interface APLPositionToBoundsMapping () @property (nonatomic, strong) id<ResizableDynamicItem> target; @end !@implementation APLPositionToBoundsMapping !- (instancetype)initWithTarget:(id<ResizableDynamicItem>)target { if ((self = [super init])) { _target = target; } return self; } !- (CGRect)bounds { return self.target.bounds; // Pass through } !- (CGPoint)center { return CGPointMake(self.target.bounds.size.width, self.target.bounds.size.height); } !- (void)setCenter:(CGPoint)center { self.target.bounds = CGRectMake(0, 0, center.x, center.y); } !- (CGAffineTransform)transform { return self.target.transform; // Pass through } !- (void)setTransform:(CGAffineTransform)transform { self.target.transform = transform; // Pass through } @end

Page 278: Hackatron - UIKit Dynamics

Example 2: remap center property#import "APLPositionToBoundsMapping.h" !@interface APLPositionToBoundsMapping () @property (nonatomic, strong) id<ResizableDynamicItem> target; @end !@implementation APLPositionToBoundsMapping !- (instancetype)initWithTarget:(id<ResizableDynamicItem>)target { if ((self = [super init])) { _target = target; } return self; } !- (CGRect)bounds { return self.target.bounds; // Pass through } !- (CGPoint)center { return CGPointMake(self.target.bounds.size.width, self.target.bounds.size.height); } !- (void)setCenter:(CGPoint)center { self.target.bounds = CGRectMake(0, 0, center.x, center.y); } !- (CGAffineTransform)transform { return self.target.transform; // Pass through } !- (void)setTransform:(CGAffineTransform)transform { self.target.transform = transform; // Pass through } @end

Page 279: Hackatron - UIKit Dynamics

Example 2: remap center property@import UIKit; !!@interface APLCustomDynamicItemViewController : UIViewController @end !!@interface APLCustomDynamicItemViewController () @property (nonatomic, weak) IBOutlet UIButton *button1; @property (nonatomic, readwrite) CGRect button1Bounds; @property (nonatomic, strong) UIDynamicAnimator *animator; @end !!@implementation APLCustomDynamicItemViewController !- (void)viewDidLoad { ! // Save the button's initial bounds. self.button1Bounds = self.button1.bounds; // Force the button image to scale with its bounds. self.button1.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill; self.button1.contentVerticalAlignment = UIControlContentHorizontalAlignmentFill; } !// ... continue !@end

Page 280: Hackatron - UIKit Dynamics

Example 2: remap center property@import UIKit; !!@interface APLCustomDynamicItemViewController : UIViewController @end !!@interface APLCustomDynamicItemViewController () @property (nonatomic, weak) IBOutlet UIButton *button1; @property (nonatomic, readwrite) CGRect button1Bounds; @property (nonatomic, strong) UIDynamicAnimator *animator; @end !!@implementation APLCustomDynamicItemViewController !- (void)viewDidLoad { ! // Save the button's initial bounds. self.button1Bounds = self.button1.bounds; // Force the button image to scale with its bounds. self.button1.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill; self.button1.contentVerticalAlignment = UIControlContentHorizontalAlignmentFill; } !// ... continue !@end

Page 281: Hackatron - UIKit Dynamics

Example 2: remap center property!@implementation APLCustomDynamicItemViewController !... !- (IBAction)buttonAction:(id)sender { ! // Reset the buttons bounds to their initial state. self.button1.bounds = self.button1Bounds; UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; APLPositionToBoundsMapping *buttonBoundsDynamicItem; buttonBoundsDynamicItem =[[APLPositionToBoundsMapping alloc] initWithTarget:sender]; ! UIAttachmentBehavior *attachment; attachment = [[UIAttachmentBehavior alloc] initWithItem:buttonBoundsDynamicItem attachedToAnchor:buttonBoundsDynamicItem.center]; [attachment setFrequency:2.0]; [attachment setDamping:0.3]; [animator addBehavior:attachment]; UIPushBehavior *pushBehavior; pushBehavior = [[UIPushBehavior alloc] initWithItems:@[buttonBoundsDynamicItem] mode:UIPushBehaviorModeInstantaneous]; pushBehavior.angle = M_PI_4; pushBehavior.magnitude = 2.0; ! [animator addBehavior:pushBehavior]; self.animator = animator; } @end

Page 282: Hackatron - UIKit Dynamics

Example 2: remap center property!@implementation APLCustomDynamicItemViewController !... !- (IBAction)buttonAction:(id)sender { ! // Reset the buttons bounds to their initial state. self.button1.bounds = self.button1Bounds; UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; APLPositionToBoundsMapping *buttonBoundsDynamicItem; buttonBoundsDynamicItem =[[APLPositionToBoundsMapping alloc] initWithTarget:sender]; ! UIAttachmentBehavior *attachment; attachment = [[UIAttachmentBehavior alloc] initWithItem:buttonBoundsDynamicItem attachedToAnchor:buttonBoundsDynamicItem.center]; [attachment setFrequency:2.0]; [attachment setDamping:0.3]; [animator addBehavior:attachment]; UIPushBehavior *pushBehavior; pushBehavior = [[UIPushBehavior alloc] initWithItems:@[buttonBoundsDynamicItem] mode:UIPushBehaviorModeInstantaneous]; pushBehavior.angle = M_PI_4; pushBehavior.magnitude = 2.0; ! [animator addBehavior:pushBehavior]; self.animator = animator; } @end

Page 283: Hackatron - UIKit Dynamics

Example 2: remap center property!@implementation APLCustomDynamicItemViewController !... !- (IBAction)buttonAction:(id)sender { ! // Reset the buttons bounds to their initial state. self.button1.bounds = self.button1Bounds; UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; APLPositionToBoundsMapping *buttonBoundsDynamicItem; buttonBoundsDynamicItem =[[APLPositionToBoundsMapping alloc] initWithTarget:sender]; ! UIAttachmentBehavior *attachment; attachment = [[UIAttachmentBehavior alloc] initWithItem:buttonBoundsDynamicItem attachedToAnchor:buttonBoundsDynamicItem.center]; [attachment setFrequency:2.0]; [attachment setDamping:0.3]; [animator addBehavior:attachment]; UIPushBehavior *pushBehavior; pushBehavior = [[UIPushBehavior alloc] initWithItems:@[buttonBoundsDynamicItem] mode:UIPushBehaviorModeInstantaneous]; pushBehavior.angle = M_PI_4; pushBehavior.magnitude = 2.0; ! [animator addBehavior:pushBehavior]; self.animator = animator; } @end

Page 284: Hackatron - UIKit Dynamics

Example 2: remap center property!@implementation APLCustomDynamicItemViewController !... !- (IBAction)buttonAction:(id)sender { ! // Reset the buttons bounds to their initial state. self.button1.bounds = self.button1Bounds; UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; APLPositionToBoundsMapping *buttonBoundsDynamicItem; buttonBoundsDynamicItem =[[APLPositionToBoundsMapping alloc] initWithTarget:sender]; ! UIAttachmentBehavior *attachment; attachment = [[UIAttachmentBehavior alloc] initWithItem:buttonBoundsDynamicItem attachedToAnchor:buttonBoundsDynamicItem.center]; [attachment setFrequency:2.0]; [attachment setDamping:0.3]; [animator addBehavior:attachment]; UIPushBehavior *pushBehavior; pushBehavior = [[UIPushBehavior alloc] initWithItems:@[buttonBoundsDynamicItem] mode:UIPushBehaviorModeInstantaneous]; pushBehavior.angle = M_PI_4; pushBehavior.magnitude = 2.0; ! [animator addBehavior:pushBehavior]; self.animator = animator; } @end

Page 285: Hackatron - UIKit Dynamics

Example 2: remap center property!@implementation APLCustomDynamicItemViewController !... !- (IBAction)buttonAction:(id)sender { ! // Reset the buttons bounds to their initial state. self.button1.bounds = self.button1Bounds; UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; APLPositionToBoundsMapping *buttonBoundsDynamicItem; buttonBoundsDynamicItem =[[APLPositionToBoundsMapping alloc] initWithTarget:sender]; ! UIAttachmentBehavior *attachment; attachment = [[UIAttachmentBehavior alloc] initWithItem:buttonBoundsDynamicItem attachedToAnchor:buttonBoundsDynamicItem.center]; [attachment setFrequency:2.0]; [attachment setDamping:0.3]; [animator addBehavior:attachment]; UIPushBehavior *pushBehavior; pushBehavior = [[UIPushBehavior alloc] initWithItems:@[buttonBoundsDynamicItem] mode:UIPushBehaviorModeInstantaneous]; pushBehavior.angle = M_PI_4; pushBehavior.magnitude = 2.0; ! [animator addBehavior:pushBehavior]; self.animator = animator; } @end

Page 286: Hackatron - UIKit Dynamics

Example 2: remap center property!@implementation APLCustomDynamicItemViewController !... !- (IBAction)buttonAction:(id)sender { ! // Reset the buttons bounds to their initial state. self.button1.bounds = self.button1Bounds; UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; APLPositionToBoundsMapping *buttonBoundsDynamicItem; buttonBoundsDynamicItem =[[APLPositionToBoundsMapping alloc] initWithTarget:sender]; ! UIAttachmentBehavior *attachment; attachment = [[UIAttachmentBehavior alloc] initWithItem:buttonBoundsDynamicItem attachedToAnchor:buttonBoundsDynamicItem.center]; [attachment setFrequency:2.0]; [attachment setDamping:0.3]; [animator addBehavior:attachment]; UIPushBehavior *pushBehavior; pushBehavior = [[UIPushBehavior alloc] initWithItems:@[buttonBoundsDynamicItem] mode:UIPushBehaviorModeInstantaneous]; pushBehavior.angle = M_PI_4; pushBehavior.magnitude = 2.0; ! [animator addBehavior:pushBehavior]; self.animator = animator; } @end

Page 287: Hackatron - UIKit Dynamics

Example 2: remap center property!@implementation APLCustomDynamicItemViewController !... !- (IBAction)buttonAction:(id)sender { ! // Reset the buttons bounds to their initial state. self.button1.bounds = self.button1Bounds; UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; APLPositionToBoundsMapping *buttonBoundsDynamicItem; buttonBoundsDynamicItem =[[APLPositionToBoundsMapping alloc] initWithTarget:sender]; ! UIAttachmentBehavior *attachment; attachment = [[UIAttachmentBehavior alloc] initWithItem:buttonBoundsDynamicItem attachedToAnchor:buttonBoundsDynamicItem.center]; [attachment setFrequency:2.0]; [attachment setDamping:0.3]; [animator addBehavior:attachment]; UIPushBehavior *pushBehavior; pushBehavior = [[UIPushBehavior alloc] initWithItems:@[buttonBoundsDynamicItem] mode:UIPushBehaviorModeInstantaneous]; pushBehavior.angle = M_PI_4; pushBehavior.magnitude = 2.0; ! [animator addBehavior:pushBehavior]; self.animator = animator; } @end

Page 288: Hackatron - UIKit Dynamics

Example 2: remap center property

Page 289: Hackatron - UIKit Dynamics

19:18:56.545 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.547 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.549 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.550 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.551 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.552 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.553 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.556 Animator is running 19:18:56.561 -[APLPositionToBoundsMapping setCenter:]:81 {150, 45.999996} 19:18:56.563 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.575 -[APLPositionToBoundsMapping setCenter:]:81 {153.80513, 49.805138} 19:18:56.578 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3838192e-06, 1.3838192e-06, 1, 0, 0] !... !19:19:02.527 -[APLPositionToBoundsMapping setCenter:]:81 {150.07957, 46.079357} 19:19:02.529 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7647307e-06, 2.7647307e-06, 1, 0, 0] 19:19:02.542 -[APLPositionToBoundsMapping setCenter:]:81 {150.07266, 46.072491} 19:19:02.545 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7667704e-06, 2.7667704e-06, 1, 0, 0] 19:19:02.547 Animator stopped

Example 2: remap center property

Page 290: Hackatron - UIKit Dynamics

19:18:56.545 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.547 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.549 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.550 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.551 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.552 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.553 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.556 Animator is running 19:18:56.561 -[APLPositionToBoundsMapping setCenter:]:81 {150, 45.999996} 19:18:56.563 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.575 -[APLPositionToBoundsMapping setCenter:]:81 {153.80513, 49.805138} 19:18:56.578 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3838192e-06, 1.3838192e-06, 1, 0, 0] !... !19:19:02.527 -[APLPositionToBoundsMapping setCenter:]:81 {150.07957, 46.079357} 19:19:02.529 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7647307e-06, 2.7647307e-06, 1, 0, 0] 19:19:02.542 -[APLPositionToBoundsMapping setCenter:]:81 {150.07266, 46.072491} 19:19:02.545 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7667704e-06, 2.7667704e-06, 1, 0, 0] 19:19:02.547 Animator stopped

Example 2: remap center property

Page 291: Hackatron - UIKit Dynamics

19:18:56.545 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.547 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.549 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.550 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.551 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.552 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.553 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.556 Animator is running 19:18:56.561 -[APLPositionToBoundsMapping setCenter:]:81 {150, 45.999996} 19:18:56.563 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.575 -[APLPositionToBoundsMapping setCenter:]:81 {153.80513, 49.805138} 19:18:56.578 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3838192e-06, 1.3838192e-06, 1, 0, 0] !... !19:19:02.527 -[APLPositionToBoundsMapping setCenter:]:81 {150.07957, 46.079357} 19:19:02.529 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7647307e-06, 2.7647307e-06, 1, 0, 0] 19:19:02.542 -[APLPositionToBoundsMapping setCenter:]:81 {150.07266, 46.072491} 19:19:02.545 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7667704e-06, 2.7667704e-06, 1, 0, 0] 19:19:02.547 Animator stopped

Example 2: remap center property

Page 292: Hackatron - UIKit Dynamics

19:18:56.545 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.547 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.549 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.550 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.551 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.552 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.553 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.556 Animator is running 19:18:56.561 -[APLPositionToBoundsMapping setCenter:]:81 {150, 45.999996} 19:18:56.563 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.575 -[APLPositionToBoundsMapping setCenter:]:81 {153.80513, 49.805138} 19:18:56.578 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3838192e-06, 1.3838192e-06, 1, 0, 0] !... !19:19:02.527 -[APLPositionToBoundsMapping setCenter:]:81 {150.07957, 46.079357} 19:19:02.529 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7647307e-06, 2.7647307e-06, 1, 0, 0] 19:19:02.542 -[APLPositionToBoundsMapping setCenter:]:81 {150.07266, 46.072491} 19:19:02.545 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7667704e-06, 2.7667704e-06, 1, 0, 0] 19:19:02.547 Animator stopped

Example 2: remap center property

Page 293: Hackatron - UIKit Dynamics

19:18:56.545 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.547 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.549 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.550 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.551 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.552 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.553 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.556 Animator is running 19:18:56.561 -[APLPositionToBoundsMapping setCenter:]:81 {150, 45.999996} 19:18:56.563 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.575 -[APLPositionToBoundsMapping setCenter:]:81 {153.80513, 49.805138} 19:18:56.578 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3838192e-06, 1.3838192e-06, 1, 0, 0] !... !19:19:02.527 -[APLPositionToBoundsMapping setCenter:]:81 {150.07957, 46.079357} 19:19:02.529 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7647307e-06, 2.7647307e-06, 1, 0, 0] 19:19:02.542 -[APLPositionToBoundsMapping setCenter:]:81 {150.07266, 46.072491} 19:19:02.545 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7667704e-06, 2.7667704e-06, 1, 0, 0] 19:19:02.547 Animator stopped

Example 2: remap center property

Page 294: Hackatron - UIKit Dynamics

19:18:56.545 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.547 -[APLPositionToBoundsMapping center]:68 {150, 46} 19:18:56.549 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.550 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.551 -[APLPositionToBoundsMapping bounds]:55 {{0, 0}, {150, 46}} 19:18:56.552 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.553 -[APLPositionToBoundsMapping transform]:94 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.556 Animator is running 19:18:56.561 -[APLPositionToBoundsMapping setCenter:]:81 {150, 45.999996} 19:18:56.563 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3833854e-06, 1.3833854e-06, 1, 0, 0] 19:18:56.575 -[APLPositionToBoundsMapping setCenter:]:81 {153.80513, 49.805138} 19:18:56.578 -[APLPositionToBoundsMapping setTransform:]:107 [1, -1.3838192e-06, 1.3838192e-06, 1, 0, 0] !... !19:19:02.527 -[APLPositionToBoundsMapping setCenter:]:81 {150.07957, 46.079357} 19:19:02.529 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7647307e-06, 2.7647307e-06, 1, 0, 0] 19:19:02.542 -[APLPositionToBoundsMapping setCenter:]:81 {150.07266, 46.072491} 19:19:02.545 -[APLPositionToBoundsMapping setTransform:]:107 [1, -2.7667704e-06, 2.7667704e-06, 1, 0, 0] 19:19:02.547 Animator stopped

Example 2: remap center property

Page 295: Hackatron - UIKit Dynamics

Dynamics & Collection View

Page 296: Hackatron - UIKit Dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

Page 297: Hackatron - UIKit Dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

Page 298: Hackatron - UIKit Dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

• How

Page 299: Hackatron - UIKit Dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

• How

•Use UIKit Dynamics for very specific animations

Page 300: Hackatron - UIKit Dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

• How

•Use UIKit Dynamics for very specific animations

• create UIDynamicAnimator as needed and discard later

Page 301: Hackatron - UIKit Dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

• How

•Use UIKit Dynamics for very specific animations

• create UIDynamicAnimator as needed and discard later

•Animate a subset of a layout

Page 302: Hackatron - UIKit Dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

• How

•Use UIKit Dynamics for very specific animations

• create UIDynamicAnimator as needed and discard later

•Animate a subset of a layout

•Build an entire layout with UIKit Dynamics

Page 303: Hackatron - UIKit Dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

• How

•Use UIKit Dynamics for very specific animations

• create UIDynamicAnimator as needed and discard later

•Animate a subset of a layout

•Build an entire layout with UIKit Dynamics

•performace: better for small data source

Page 304: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

Page 305: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

•Create the UIDynamicAnimator with layout instance UICollectionViewLayout *layout = ...;

animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout :layout];

Page 306: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

•Create the UIDynamicAnimator with layout instance UICollectionViewLayout *layout = ...;

animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout :layout];

Page 307: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

•Create the UIDynamicAnimator with layout instance UICollectionViewLayout *layout = ...;

animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout :layout];

Page 308: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

•Create the UIDynamicAnimator with layout instance UICollectionViewLayout *layout = ...;

animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout :layout];

Page 309: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

•Create the UIDynamicAnimator with layout instance UICollectionViewLayout *layout = ...;

animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout :layout];

• Create behaviors and add UICollectionViewLayoutAttributes to these behaviors

Page 310: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

•Create the UIDynamicAnimator with layout instance UICollectionViewLayout *layout = ...;

animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout :layout];

• Create behaviors and add UICollectionViewLayoutAttributes to these behaviors UICollectionViewLayoutAttributes *attribute = ...;

UIAttachmentBehavior *spring;

spring = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:anchorPoint];

...

Page 311: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

•Create the UIDynamicAnimator with layout instance UICollectionViewLayout *layout = ...;

animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout :layout];

• Create behaviors and add UICollectionViewLayoutAttributes to these behaviors UICollectionViewLayoutAttributes *attribute = ...;

UIAttachmentBehavior *spring;

spring = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:anchorPoint];

...

Page 312: Hackatron - UIKit Dynamics

Basic steps

•Create the the UICollectionViewLayout instance

•Create the UIDynamicAnimator with layout instance UICollectionViewLayout *layout = ...;

animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout :layout];

• Create behaviors and add UICollectionViewLayoutAttributes to these behaviors UICollectionViewLayoutAttributes *attribute = ...;

UIAttachmentBehavior *spring;

spring = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:anchorPoint];

...

Page 313: Hackatron - UIKit Dynamics

UIKit Dynamics Support for UICollectionViews

Page 314: Hackatron - UIKit Dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

Page 315: Hackatron - UIKit Dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

•Dynamics automatically invalidate layout as needed

Page 316: Hackatron - UIKit Dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

•Dynamics automatically invalidate layout as needed

•Dynamics pause the animator when a UICollectionViewLayout is no longer associated with the UICollectionView

Page 317: Hackatron - UIKit Dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

•Dynamics automatically invalidate layout as needed

•Dynamics pause the animator when a UICollectionViewLayout is no longer associated with the UICollectionView

• UIDynamicAnimator provide conveniece method to implemement custom layout

Page 318: Hackatron - UIKit Dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

•Dynamics automatically invalidate layout as needed

•Dynamics pause the animator when a UICollectionViewLayout is no longer associated with the UICollectionView

• UIDynamicAnimator provide conveniece method to implemement custom layout- (UICollectionViewLayoutAttributes*)layoutAttributesForCellAtIndexPath:(NSIndexPath*)ip;

Page 319: Hackatron - UIKit Dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

•Dynamics automatically invalidate layout as needed

•Dynamics pause the animator when a UICollectionViewLayout is no longer associated with the UICollectionView

• UIDynamicAnimator provide conveniece method to implemement custom layout- (UICollectionViewLayoutAttributes*)layoutAttributesForCellAtIndexPath:(NSIndexPath*)ip;

- (UICollectionViewLayoutAttributes*)layoutAttributesForSupplementaryViewOfKind:(NSString *)k atIndexPath:(NSIndexPath *)ip;

Page 320: Hackatron - UIKit Dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

•Dynamics automatically invalidate layout as needed

•Dynamics pause the animator when a UICollectionViewLayout is no longer associated with the UICollectionView

• UIDynamicAnimator provide conveniece method to implemement custom layout- (UICollectionViewLayoutAttributes*)layoutAttributesForCellAtIndexPath:(NSIndexPath*)ip;

- (UICollectionViewLayoutAttributes*)layoutAttributesForSupplementaryViewOfKind:(NSString *)k atIndexPath:(NSIndexPath *)ip;

- (UICollectionViewLayoutAttributes*)layoutAttributesForDecorationViewOfKind:(NSString*)k atIndexPath:(NSIndexPath *)ip;

Page 321: Hackatron - UIKit Dynamics

Collection View Layout Updates

Page 322: Hackatron - UIKit Dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: 

Page 323: Hackatron - UIKit Dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: • prepareLayout

Page 324: Hackatron - UIKit Dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: • prepareLayout •used when instantiate an animator or create initial state 

Page 325: Hackatron - UIKit Dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: • prepareLayout •used when instantiate an animator or create initial state 

•prepareForCollectionViewUpdates

Page 326: Hackatron - UIKit Dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: • prepareLayout •used when instantiate an animator or create initial state 

•prepareForCollectionViewUpdates

•opportunity to add UICollectionViewLayoutAttributes to behaviors.

Page 327: Hackatron - UIKit Dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: • prepareLayout •used when instantiate an animator or create initial state 

•prepareForCollectionViewUpdates

•opportunity to add UICollectionViewLayoutAttributes to behaviors.

• layoutAttributesForElementsInRect

Page 328: Hackatron - UIKit Dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: • prepareLayout •used when instantiate an animator or create initial state 

•prepareForCollectionViewUpdates

•opportunity to add UICollectionViewLayoutAttributes to behaviors.

• layoutAttributesForElementsInRect • UIDynamicAnimator has itemsInRect

Page 329: Hackatron - UIKit Dynamics

Example: collection view

Page 330: Hackatron - UIKit Dynamics

Example: collection view

@interface DPProportionalSpringFlowLayout : UICollectionViewFlowLayout @end !!!@interface DPProportionalSpringFlowLayout () !@property (strong, readwrite, nonatomic) UIDynamicAnimator *dynamicAnimator; !@end !@implementation DPProportionalSpringFlowLayout !- (CGSize)itemSize { return CGSizeMake(CGRectGetWidth(self.collectionView.frame), 50.0f); } !- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { return [self.dynamicAnimator itemsInRect:rect]; } !- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { return [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath]; } !... // continue !@end

Page 331: Hackatron - UIKit Dynamics

Example: collection view

@interface DPProportionalSpringFlowLayout : UICollectionViewFlowLayout @end !!!@interface DPProportionalSpringFlowLayout () !@property (strong, readwrite, nonatomic) UIDynamicAnimator *dynamicAnimator; !@end !@implementation DPProportionalSpringFlowLayout !- (CGSize)itemSize { return CGSizeMake(CGRectGetWidth(self.collectionView.frame), 50.0f); } !- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { return [self.dynamicAnimator itemsInRect:rect]; } !- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { return [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath]; } !... // continue !@end

Page 332: Hackatron - UIKit Dynamics

Example: collection view

@interface DPProportionalSpringFlowLayout : UICollectionViewFlowLayout @end !!!@interface DPProportionalSpringFlowLayout () !@property (strong, readwrite, nonatomic) UIDynamicAnimator *dynamicAnimator; !@end !@implementation DPProportionalSpringFlowLayout !- (CGSize)itemSize { return CGSizeMake(CGRectGetWidth(self.collectionView.frame), 50.0f); } !- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { return [self.dynamicAnimator itemsInRect:rect]; } !- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { return [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath]; } !... // continue !@end

Page 333: Hackatron - UIKit Dynamics

Example: collection view

@interface DPProportionalSpringFlowLayout : UICollectionViewFlowLayout @end !!!@interface DPProportionalSpringFlowLayout () !@property (strong, readwrite, nonatomic) UIDynamicAnimator *dynamicAnimator; !@end !@implementation DPProportionalSpringFlowLayout !- (CGSize)itemSize { return CGSizeMake(CGRectGetWidth(self.collectionView.frame), 50.0f); } !- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { return [self.dynamicAnimator itemsInRect:rect]; } !- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { return [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath]; } !... // continue !@end

Page 334: Hackatron - UIKit Dynamics

Example: collection view

@interface DPProportionalSpringFlowLayout : UICollectionViewFlowLayout @end !!!@interface DPProportionalSpringFlowLayout () !@property (strong, readwrite, nonatomic) UIDynamicAnimator *dynamicAnimator; !@end !@implementation DPProportionalSpringFlowLayout !- (CGSize)itemSize { return CGSizeMake(CGRectGetWidth(self.collectionView.frame), 50.0f); } !- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { return [self.dynamicAnimator itemsInRect:rect]; } !- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { return [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath]; } !... // continue !@end

Page 335: Hackatron - UIKit Dynamics

Example: collection view

@interface DPProportionalSpringFlowLayout : UICollectionViewFlowLayout @end !!!@interface DPProportionalSpringFlowLayout () !@property (strong, readwrite, nonatomic) UIDynamicAnimator *dynamicAnimator; !@end !@implementation DPProportionalSpringFlowLayout !- (CGSize)itemSize { return CGSizeMake(CGRectGetWidth(self.collectionView.frame), 50.0f); } !- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { return [self.dynamicAnimator itemsInRect:rect]; } !- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { return [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath]; } !... // continue !@end

Page 336: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout !// ... continue from previous slide !- (void)prepareLayout { [super prepareLayout]; ! if (nil == [self dynamicAnimator]) { ! self.dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; ! CGSize contentSize = [self collectionViewContentSize]; CGRect contentRect = { CGPointZero, contentSize }; ! NSArray *layoutAttributes = [super layoutAttributesForElementsInRect:contentRect]; // create spring behavior for each item for (UICollectionViewLayoutAttributes *attribute in layoutAttributes) { ! UIAttachmentBehavior *springBehavior; springBehavior = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:[attribute center]]; springBehavior.length = 0.0; springBehavior.damping = 0.5; springBehavior.frequency = 0.8; [self.dynamicAnimator addBehavior:springBehavior]; } } } !// ... continue !@end

Page 337: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout !// ... continue from previous slide !- (void)prepareLayout { [super prepareLayout]; ! if (nil == [self dynamicAnimator]) { ! self.dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; ! CGSize contentSize = [self collectionViewContentSize]; CGRect contentRect = { CGPointZero, contentSize }; ! NSArray *layoutAttributes = [super layoutAttributesForElementsInRect:contentRect]; // create spring behavior for each item for (UICollectionViewLayoutAttributes *attribute in layoutAttributes) { ! UIAttachmentBehavior *springBehavior; springBehavior = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:[attribute center]]; springBehavior.length = 0.0; springBehavior.damping = 0.5; springBehavior.frequency = 0.8; [self.dynamicAnimator addBehavior:springBehavior]; } } } !// ... continue !@end

Page 338: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout !// ... continue from previous slide !- (void)prepareLayout { [super prepareLayout]; ! if (nil == [self dynamicAnimator]) { ! self.dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; ! CGSize contentSize = [self collectionViewContentSize]; CGRect contentRect = { CGPointZero, contentSize }; ! NSArray *layoutAttributes = [super layoutAttributesForElementsInRect:contentRect]; // create spring behavior for each item for (UICollectionViewLayoutAttributes *attribute in layoutAttributes) { ! UIAttachmentBehavior *springBehavior; springBehavior = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:[attribute center]]; springBehavior.length = 0.0; springBehavior.damping = 0.5; springBehavior.frequency = 0.8; [self.dynamicAnimator addBehavior:springBehavior]; } } } !// ... continue !@end

Page 339: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout !// ... continue from previous slide !- (void)prepareLayout { [super prepareLayout]; ! if (nil == [self dynamicAnimator]) { ! self.dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; ! CGSize contentSize = [self collectionViewContentSize]; CGRect contentRect = { CGPointZero, contentSize }; ! NSArray *layoutAttributes = [super layoutAttributesForElementsInRect:contentRect]; // create spring behavior for each item for (UICollectionViewLayoutAttributes *attribute in layoutAttributes) { ! UIAttachmentBehavior *springBehavior; springBehavior = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:[attribute center]]; springBehavior.length = 0.0; springBehavior.damping = 0.5; springBehavior.frequency = 0.8; [self.dynamicAnimator addBehavior:springBehavior]; } } } !// ... continue !@end

Page 340: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout !// ... continue from previous slide !- (void)prepareLayout { [super prepareLayout]; ! if (nil == [self dynamicAnimator]) { ! self.dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; ! CGSize contentSize = [self collectionViewContentSize]; CGRect contentRect = { CGPointZero, contentSize }; ! NSArray *layoutAttributes = [super layoutAttributesForElementsInRect:contentRect]; // create spring behavior for each item for (UICollectionViewLayoutAttributes *attribute in layoutAttributes) { ! UIAttachmentBehavior *springBehavior; springBehavior = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:[attribute center]]; springBehavior.length = 0.0; springBehavior.damping = 0.5; springBehavior.frequency = 0.8; [self.dynamicAnimator addBehavior:springBehavior]; } } } !// ... continue !@end

Page 341: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout !// ... continue from previous slide !- (void)prepareLayout { [super prepareLayout]; ! if (nil == [self dynamicAnimator]) { ! self.dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; ! CGSize contentSize = [self collectionViewContentSize]; CGRect contentRect = { CGPointZero, contentSize }; ! NSArray *layoutAttributes = [super layoutAttributesForElementsInRect:contentRect]; // create spring behavior for each item for (UICollectionViewLayoutAttributes *attribute in layoutAttributes) { ! UIAttachmentBehavior *springBehavior; springBehavior = [[UIAttachmentBehavior alloc] initWithItem:attribute attachedToAnchor:[attribute center]]; springBehavior.length = 0.0; springBehavior.damping = 0.5; springBehavior.frequency = 0.8; [self.dynamicAnimator addBehavior:springBehavior]; } } } !// ... continue !@end

Page 342: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 343: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 344: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 345: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 346: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 347: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 348: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 349: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 350: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 351: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPProportionalSpringFlowLayout // ... continue form previous slide !- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { UIScrollView *scrollView = [self collectionView]; CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y; CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView]; for (UIAttachmentBehavior *springBehavior in [self.dynamicAnimator behaviors]) { CGPoint anchorPoint = [springBehavior anchorPoint]; CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y); CGFloat scrollResistance = distanceFromTouch / 500.0f; ! UICollectionViewLayoutAttributes *attribute = [springBehavior.items firstObject]; CGPoint center = [attribute center]; CGFloat springStretch = scrollDelta * scrollResistance; if (scroll > 0) { center.y += MIN(scrollDelta, scrollDelta * springStretch); } else { center.y += MAX(scrollDelta, scrollDelta * springStretch); } ! attribute.center = center; [self.dynamicAnimator updateItemUsingCurrentState:attribute]; } return NO; } @end

Page 352: Hackatron - UIKit Dynamics

Example: collection view

@import UIKit; !@interface DPDynamicCollectionViewViewController : UIViewController @end !!!!!const NSInteger kCellCount = 20; !@interface DPDynamicCollectionViewViewController() <UICollectionViewDataSource, UICollectionViewDelegate> ! @property (weak, nonatomic) IBOutlet UICollectionView *collectionView; ! @property (strong, nonatomic) UICollectionViewFlowLayout *flowLayout; ! @property (strong, nonatomic) NSMutableArray *colors; !@end !!

Page 353: Hackatron - UIKit Dynamics

Example: collection view

@import UIKit; !@interface DPDynamicCollectionViewViewController : UIViewController @end !!!!!const NSInteger kCellCount = 20; !@interface DPDynamicCollectionViewViewController() <UICollectionViewDataSource, UICollectionViewDelegate> ! @property (weak, nonatomic) IBOutlet UICollectionView *collectionView; ! @property (strong, nonatomic) UICollectionViewFlowLayout *flowLayout; ! @property (strong, nonatomic) NSMutableArray *colors; !@end !!

Page 354: Hackatron - UIKit Dynamics

Example: collection view

@import UIKit; !@interface DPDynamicCollectionViewViewController : UIViewController @end !!!!!const NSInteger kCellCount = 20; !@interface DPDynamicCollectionViewViewController() <UICollectionViewDataSource, UICollectionViewDelegate> ! @property (weak, nonatomic) IBOutlet UICollectionView *collectionView; ! @property (strong, nonatomic) UICollectionViewFlowLayout *flowLayout; ! @property (strong, nonatomic) NSMutableArray *colors; !@end !!

Page 355: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPDynamicCollectionViewViewController !... !- (void)viewDidLoad { [super viewDidLoad]; ! self.colors = [self cellColors]; ! [self.collectionView registerClass:[DPCollectionViewCell class] forCellWithReuseIdentifier:[DPCollectionViewCell cellIdentifier]]; self.flowLayout = [[DPProportionalSpringFlowLayout alloc] init]; [self.collectionView setCollectionViewLayout:[self flowLayout]]; !} !// ... continue !!!!@end

Page 356: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPDynamicCollectionViewViewController !... !- (void)viewDidLoad { [super viewDidLoad]; ! self.colors = [self cellColors]; ! [self.collectionView registerClass:[DPCollectionViewCell class] forCellWithReuseIdentifier:[DPCollectionViewCell cellIdentifier]]; self.flowLayout = [[DPProportionalSpringFlowLayout alloc] init]; [self.collectionView setCollectionViewLayout:[self flowLayout]]; !} !// ... continue !!!!@end

Page 357: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPDynamicCollectionViewViewController !... !- (void)viewDidLoad { [super viewDidLoad]; ! self.colors = [self cellColors]; ! [self.collectionView registerClass:[DPCollectionViewCell class] forCellWithReuseIdentifier:[DPCollectionViewCell cellIdentifier]]; self.flowLayout = [[DPProportionalSpringFlowLayout alloc] init]; [self.collectionView setCollectionViewLayout:[self flowLayout]]; !} !// ... continue !!!!@end

Page 358: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPDynamicCollectionViewViewController !// ... continue form previous slide !!- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return kCellCount; } !- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { ! DPCollectionViewCell *cell; cell = (DPCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier: [DPCollectionViewCell cellIdentifier] forIndexPath:indexPath]; ! [self configureCell:cell forItemAtIndexPath:indexPath]; return cell; } !@end

Page 359: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPDynamicCollectionViewViewController !// ... continue form previous slide !!- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return kCellCount; } !- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { ! DPCollectionViewCell *cell; cell = (DPCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier: [DPCollectionViewCell cellIdentifier] forIndexPath:indexPath]; ! [self configureCell:cell forItemAtIndexPath:indexPath]; return cell; } !@end

Page 360: Hackatron - UIKit Dynamics

Example: collection view

@implementation DPDynamicCollectionViewViewController !// ... continue form previous slide !!- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return kCellCount; } !- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { ! DPCollectionViewCell *cell; cell = (DPCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier: [DPCollectionViewCell cellIdentifier] forIndexPath:indexPath]; ! [self configureCell:cell forItemAtIndexPath:indexPath]; return cell; } !@end

Page 361: Hackatron - UIKit Dynamics

Conclusion

Page 362: Hackatron - UIKit Dynamics

Tips

•Build iteratively

Page 363: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

Page 364: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

Page 365: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

Page 366: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

•Collision only for rectangle objects

Page 367: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

•Collision only for rectangle objects

Page 368: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

•Collision only for rectangle objects

•Not an physics-accurate simulation tool

Page 369: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

•Collision only for rectangle objects

•Not an physics-accurate simulation tool

•Not for games

Page 370: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

•Collision only for rectangle objects

•Not an physics-accurate simulation tool

•Not for games

• use Sprite Kit

Page 371: Hackatron - UIKit Dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

•Collision only for rectangle objects

•Not an physics-accurate simulation tool

•Not for games

• use Sprite Kit

•Focus on the user experience

Page 372: Hackatron - UIKit Dynamics

Animations and Interactions

•Can combine all previous techniques

Page 373: Hackatron - UIKit Dynamics

Animations and Interactions

•Can combine all previous techniques

•Core Animation

Page 374: Hackatron - UIKit Dynamics

Animations and Interactions

•Can combine all previous techniques

•Core Animation

•UIView animations+(void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

Page 375: Hackatron - UIKit Dynamics

Animations and Interactions

•Can combine all previous techniques

•Core Animation

•UIView animations+(void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

•Motion effects

Page 376: Hackatron - UIKit Dynamics

Animations and Interactions

•Can combine all previous techniques

•Core Animation

•UIView animations+(void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

•Motion effects

•Gestures

Page 377: Hackatron - UIKit Dynamics

Endings

"With great power comes great responsibility."

Francois-Marie Arouet a.k.a. Voltaire

Page 378: Hackatron - UIKit Dynamics

References

•Apple documentation

•WWDC 2013 sessions206 Getting Started with UIKit Dynamics221 Advanced Techniques with UIKit Dynamics217 Exploring Scroll Views in iOS 7218 Custom Transitions Using View Controllers226 Implementing Engaging UI on iOS

Page 379: Hackatron - UIKit Dynamics

References

• 3rd party docsiOS 7 by tutorials Chap. 2 (by raywenderlich.com)Objc.io issue #5

•Example codeDynamicPlaygroundUIKit Dynamics Catalog (iOS Dev Library Sample Code)

Page 380: Hackatron - UIKit Dynamics

Q & A

Page 381: Hackatron - UIKit Dynamics
Page 382: Hackatron - UIKit Dynamics

… and one more thing

Page 383: Hackatron - UIKit Dynamics

It’s beer O’Clock

Page 384: Hackatron - UIKit Dynamics

THANKS