#pragma conf 2013 - uikit dynamics

368
Renzo G. Pretto iOS Developer UIKit Dynamics

Upload: renzo-pretto

Post on 15-Jan-2015

335 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: #pragma conf 2013  - UIKit dynamics

Renzo G. PrettoiOS Developer

UIKit Dynamics

Page 2: #pragma conf 2013  - UIKit dynamics

Who’s talking

Page 3: #pragma conf 2013  - UIKit dynamics

Who’s talking

Page 4: #pragma conf 2013  - UIKit dynamics

About me

Renzo iOS DeveloperH-art!

#pragma mark [email protected]!

@rgpretto

Page 5: #pragma conf 2013  - UIKit dynamics

Conference Hashtag

#pragmaconf

Page 6: #pragma conf 2013  - UIKit dynamics

Today Agenda

• Introduction and core concepts

Page 7: #pragma conf 2013  - UIKit dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

Page 8: #pragma conf 2013  - UIKit dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

Page 9: #pragma conf 2013  - UIKit dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

•Advanced concepts

Page 10: #pragma conf 2013  - UIKit dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

•Advanced concepts

•UIDynamicItem

Page 11: #pragma conf 2013  - UIKit dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

•Advanced concepts

•UIDynamicItem

•Collection View

Page 12: #pragma conf 2013  - UIKit dynamics

Today Agenda

• Introduction and core concepts

•Standard effects: dynamic behaviors

•Custom effects: custom behaviors

•Advanced concepts

•UIDynamicItem

•Collection View

•Conclusion

Page 13: #pragma conf 2013  - UIKit dynamics

UIKit Dynamics

Page 14: #pragma conf 2013  - UIKit dynamics

UIKit Dynamics

Page 15: #pragma conf 2013  - UIKit dynamics

UIKit Dynamics

Page 16: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator

Page 17: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehaviorUIDynamicBehavior

Page 18: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehaviorUIDynamicBehavior

Page 19: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehavior

View

UIDynamicBehavior

Page 20: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehavior

View View

UIDynamicBehavior

Page 21: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator

UIDynamicBehavior UIDynamicBehavior

View View View

UIDynamicBehavior

Page 22: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator Reference view

UIDynamicBehavior UIDynamicBehavior

View View View

UIDynamicBehavior

Page 23: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator Reference view

UIDynamicBehavior UIDynamicBehavior

View View View

UIDynamicBehavior

Page 24: #pragma conf 2013  - UIKit dynamics

UIDynamicAnimator

UIDynamicAnimator

Reference view

Page 25: #pragma conf 2013  - UIKit dynamics

UIDynamicAnimator

•Define the coordinate systemUIDynamicAnimator

Reference view

Page 26: #pragma conf 2013  - UIKit dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engineUIDynamicAnimator

Reference view

Page 27: #pragma conf 2013  - UIKit dynamics

UIDynamicAnimator

•Define the coordinate system

•Wraps underline engine

•Keeps track of all the associated behaviors

UIDynamicAnimator

Reference view

Page 28: #pragma conf 2013  - 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 29: #pragma conf 2013  - 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 30: #pragma conf 2013  - 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 31: #pragma conf 2013  - 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 32: #pragma conf 2013  - 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 33: #pragma conf 2013  - 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 34: #pragma conf 2013  - UIKit dynamics

UIDynamicAnimatorDelegate

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

Page 35: #pragma conf 2013  - 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 36: #pragma conf 2013  - UIKit dynamics

UIDynamicBehaviour

UIDynamicBehavior

Page 37: #pragma conf 2013  - UIKit dynamics

UIDynamicBehaviour

•Associated to UIDynamicAnimator

UIDynamicAnimator

UIDynamicBehavior

Page 38: #pragma conf 2013  - UIKit dynamics

UIDynamicBehaviour

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

UIDynamicAnimator

UIDynamicBehavior

Page 39: #pragma conf 2013  - 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 40: #pragma conf 2013  - 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 41: #pragma conf 2013  - 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 42: #pragma conf 2013  - UIKit dynamics

Behaviors Common characteristics

• Initialized with items to animate

Page 43: #pragma conf 2013  - UIKit dynamics

Behaviors Common characteristics

• Initialized with items to animate

• Items can be added to behavior at any times

Page 44: #pragma conf 2013  - UIKit dynamics

Behaviors Common characteristics

• Initialized 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 45: #pragma conf 2013  - UIKit dynamics

Behaviors Common characteristics

• Initialized 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 46: #pragma conf 2013  - UIKit dynamics

Primitive behaviors

Page 47: #pragma conf 2013  - UIKit dynamics

Default Behaviors

UIDynamicBehavior

Page 48: #pragma conf 2013  - UIKit dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior•Gravity

Page 49: #pragma conf 2013  - UIKit dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior•Collisions

•Gravity

Page 50: #pragma conf 2013  - UIKit dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

•Collisions

•Gravity

•Attachments

Page 51: #pragma conf 2013  - UIKit dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

•Collisions

•Gravity

•Attachments

•Snap

Page 52: #pragma conf 2013  - UIKit dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

•Collisions

•Gravity

•Attachments

•Snap

•Forces

Page 53: #pragma conf 2013  - UIKit dynamics

Default Behaviors

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

•Collisions

•Gravity

•Attachments

•Snap

•Forces

• Item properties

Page 54: #pragma conf 2013  - UIKit dynamics

UIGravityBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 55: #pragma conf 2013  - UIKit dynamics

UIGravityBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 56: #pragma conf 2013  - UIKit dynamics

UIGravityBehavior

Page 57: #pragma conf 2013  - 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 58: #pragma conf 2013  - 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 59: #pragma conf 2013  - 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 60: #pragma conf 2013  - 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 61: #pragma conf 2013  - 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 62: #pragma conf 2013  - UIKit dynamics

UIGravityBehavior

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

Page 63: #pragma conf 2013  - 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 64: #pragma conf 2013  - 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 65: #pragma conf 2013  - 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 66: #pragma conf 2013  - 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 67: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 68: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 69: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

Page 70: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

@interface DPGravityCollisionViewController : 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 71: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

@interface DPGravityCollisionViewController : 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 72: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

@interface DPGravityCollisionViewController : 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 73: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

@interface DPGravityCollisionViewController : 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 74: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

@interface DPGravityCollisionViewController : 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 75: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

@interface DPGravityCollisionViewController : 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 76: #pragma conf 2013  - UIKit dynamics

UICollisionBehavior

@interface DPGravityCollisionViewController : 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 77: #pragma conf 2013  - UIKit dynamics

Collision Boundaries

•Can specify different boundaries

Page 78: #pragma conf 2013  - UIKit dynamics

Collision Boundaries

•Can specify different boundaries•Reference view

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

Page 79: #pragma conf 2013  - UIKit dynamics

Collision Boundaries

•Can specify different boundaries•Reference view

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

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

Page 80: #pragma conf 2013  - 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 81: #pragma conf 2013  - 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 82: #pragma conf 2013  - 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 83: #pragma conf 2013  - 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 84: #pragma conf 2013  - UIKit dynamics

Collision Mode

•Property collisionmode

Page 85: #pragma conf 2013  - UIKit dynamics

Collision Mode

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

Page 86: #pragma conf 2013  - UIKit dynamics

Collision Mode

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

• UICollisionBehaviorModeBoundaries

Page 87: #pragma conf 2013  - UIKit dynamics

Collision Mode

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

• UICollisionBehaviorModeBoundaries• UICollisionBehaviorModeItems

Page 88: #pragma conf 2013  - UIKit dynamics

Collision Mode

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

• UICollisionBehaviorModeBoundaries• UICollisionBehaviorModeItems

• UICollisionBehaviorModeEverything (default)

Page 89: #pragma conf 2013  - UIKit dynamics

Tips

Page 90: #pragma conf 2013  - UIKit dynamics

Tips

•Can use multiple collision behaviors

Page 91: #pragma conf 2013  - 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 92: #pragma conf 2013  - 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 93: #pragma conf 2013  - UIKit dynamics

•Methods that inform collision start / end between view

UICollisionBehaviorDelegate

Page 94: #pragma conf 2013  - 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 95: #pragma conf 2013  - 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 96: #pragma conf 2013  - 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 97: #pragma conf 2013  - 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 98: #pragma conf 2013  - 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 99: #pragma conf 2013  - UIKit dynamics

UIAttachmentBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 100: #pragma conf 2013  - UIKit dynamics

UIAttachmentBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 101: #pragma conf 2013  - UIKit dynamics

UIAttachmentBehavior

Page 102: #pragma conf 2013  - 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 103: #pragma conf 2013  - 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 104: #pragma conf 2013  - 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 105: #pragma conf 2013  - 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 106: #pragma conf 2013  - 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 107: #pragma conf 2013  - 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 108: #pragma conf 2013  - UIKit dynamics

UIAttachmentBehavior

Page 109: #pragma conf 2013  - UIKit dynamics

UIAttachmentBehavior

Page 110: #pragma conf 2013  - UIKit dynamics

•View connected to an attachment point

UIAttachmentBehavior

Page 111: #pragma conf 2013  - UIKit dynamics

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

UIAttachmentBehavior

Page 112: #pragma conf 2013  - UIKit dynamics

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

•Two views connected together

UIAttachmentBehavior

Page 113: #pragma conf 2013  - 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 114: #pragma conf 2013  - 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 115: #pragma conf 2013  - 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 116: #pragma conf 2013  - 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 117: #pragma conf 2013  - UIKit dynamics

Springs

•Springs

Page 118: #pragma conf 2013  - UIKit dynamics

Springs

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

Page 119: #pragma conf 2013  - UIKit dynamics

Springs

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

Page 120: #pragma conf 2013  - UIKit dynamics

Springs

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

Page 121: #pragma conf 2013  - UIKit dynamics

UISnapBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 122: #pragma conf 2013  - UIKit dynamics

UISnapBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 123: #pragma conf 2013  - UIKit dynamics

UISnapBehavior

Page 124: #pragma conf 2013  - UIKit dynamics

UISnapBehavior

Page 125: #pragma conf 2013  - 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 126: #pragma conf 2013  - 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 127: #pragma conf 2013  - 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 128: #pragma conf 2013  - 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 129: #pragma conf 2013  - 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 130: #pragma conf 2013  - 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 131: #pragma conf 2013  - UIKit dynamics

UISnapBehavior

•Snap view in place in non rotated state

Page 132: #pragma conf 2013  - UIKit dynamics

UISnapBehavior

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

Page 133: #pragma conf 2013  - UIKit dynamics

UISnapBehavior

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

•Customize the dumping effects

Page 134: #pragma conf 2013  - 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 135: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 136: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 137: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

~F = m ~a

Page 138: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

~F = m ~a

Page 139: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

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

Page 140: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

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

~F = m ~a

Page 141: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

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

•Force vector expressed in two way:

~F = m ~a

Page 142: #pragma conf 2013  - 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 143: #pragma conf 2013  - 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 144: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

•Customize where apply this force in the view

Page 145: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

•Customize where apply this force in the view

Page 146: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

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

Page 147: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

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

Page 148: #pragma conf 2013  - UIKit dynamics

UIPushBehavior

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

Page 149: #pragma conf 2013  - 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 150: #pragma conf 2013  - 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 151: #pragma conf 2013  - UIKit dynamics

UIPushBehavior Mode

Page 152: #pragma conf 2013  - UIKit dynamics

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

UIPushBehavior Mode

Page 153: #pragma conf 2013  - UIKit dynamics

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

• UIPushBehaviorModeContinuous

UIPushBehavior Mode

Page 154: #pragma conf 2013  - UIKit dynamics

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

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

UIPushBehavior Mode

Page 155: #pragma conf 2013  - UIKit dynamics

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

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

• views accelerate

UIPushBehavior Mode

Page 156: #pragma conf 2013  - UIKit dynamics

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

• UIPushBehaviorModeContinuous • force still be applied while behaviour is active

• views accelerate

•UIPushBehaviorModeInstantaneous

UIPushBehavior Mode

Page 157: #pragma conf 2013  - UIKit dynamics

•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

UIPushBehavior Mode

Page 158: #pragma conf 2013  - UIKit dynamics

•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)

UIPushBehavior Mode

Page 159: #pragma conf 2013  - UIKit dynamics

•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

UIPushBehavior Mode

Page 160: #pragma conf 2013  - UIKit dynamics

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

UIPushBehavior Mode

Page 161: #pragma conf 2013  - UIKit dynamics

Example: force comparison

~F = m ~a

~a =~F

m

Page 162: #pragma conf 2013  - UIKit dynamics

Example: gravity comparison

Page 163: #pragma conf 2013  - UIKit dynamics

Feel The Force!

Page 164: #pragma conf 2013  - UIKit dynamics

Feel The Force!

•Gravity

Page 165: #pragma conf 2013  - UIKit dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

Page 166: #pragma conf 2013  - UIKit dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

•Push behavior in continuos mode

Page 167: #pragma conf 2013  - UIKit dynamics

Feel The Force!

•Gravity

• views accelerate with the same rate

•Push behavior in continuos mode

• the smaller views accelerate more

Page 168: #pragma conf 2013  - 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 169: #pragma conf 2013  - 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 170: #pragma conf 2013  - 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 171: #pragma conf 2013  - UIKit dynamics

Unit of Measure

•Real world: Newton

Page 172: #pragma conf 2013  - UIKit dynamics

Unit of Measure

•Real world: Newton

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

Page 173: #pragma conf 2013  - 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 174: #pragma conf 2013  - 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 175: #pragma conf 2013  - UIKit dynamics

UIDynamicItemBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 176: #pragma conf 2013  - UIKit dynamics

UIDynamicItemBehavior

UIDynamicBehavior

UIGravityBehavior

UICollisionBehavior

UIAttachmentBehavior

UISnapBehavior

UIPushBehavior

UIDynamicItemBehavior

Page 177: #pragma conf 2013  - UIKit dynamics

•Customize dynamics properties for items

UIDynamicItemBehavior

Page 178: #pragma conf 2013  - UIKit dynamics

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

UIDynamicItemBehavior

Page 179: #pragma conf 2013  - UIKit dynamics

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

UIDynamicItemBehavior

Page 180: #pragma conf 2013  - UIKit dynamics

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

UIDynamicItemBehavior

Page 181: #pragma conf 2013  - 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 182: #pragma conf 2013  - 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 183: #pragma conf 2013  - 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 184: #pragma conf 2013  - 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 185: #pragma conf 2013  - 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 186: #pragma conf 2013  - 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 187: #pragma conf 2013  - 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 188: #pragma conf 2013  - 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 189: #pragma conf 2013  - UIKit dynamics

Custom behaviors

Page 190: #pragma conf 2013  - UIKit dynamics

Custom Behavior

•Can subclass UIDynamicBehavior

Page 191: #pragma conf 2013  - 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 192: #pragma conf 2013  - 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 193: #pragma conf 2013  - UIKit dynamics

Example: gravity & collision

Page 194: #pragma conf 2013  - 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 195: #pragma conf 2013  - 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 196: #pragma conf 2013  - 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 197: #pragma conf 2013  - 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 198: #pragma conf 2013  - 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 199: #pragma conf 2013  - 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 200: #pragma conf 2013  - 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 201: #pragma conf 2013  - 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 202: #pragma conf 2013  - 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 203: #pragma conf 2013  - 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 204: #pragma conf 2013  - 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 205: #pragma conf 2013  - 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 206: #pragma conf 2013  - 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 207: #pragma conf 2013  - 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 208: #pragma conf 2013  - 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 209: #pragma conf 2013  - 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 210: #pragma conf 2013  - UIKit dynamics

Action Block

•Can define per-step actions

Page 211: #pragma conf 2013  - UIKit dynamics

Action Block

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

Page 212: #pragma conf 2013  - UIKit dynamics

Action Block

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

• UIDynamicAnimator invoke this block in each simulation step

Page 213: #pragma conf 2013  - 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 214: #pragma conf 2013  - UIKit dynamics

UIDynamicItem protocol

Page 215: #pragma conf 2013  - UIKit dynamics

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

Page 216: #pragma conf 2013  - 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 217: #pragma conf 2013  - 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 218: #pragma conf 2013  - 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 219: #pragma conf 2013  - 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 220: #pragma conf 2013  - 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 221: #pragma conf 2013  - UIKit dynamics

UIDynamicItem Protocol

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

Page 222: #pragma conf 2013  - 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 223: #pragma conf 2013  - 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 224: #pragma conf 2013  - 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 225: #pragma conf 2013  - 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 226: #pragma conf 2013  - 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 227: #pragma conf 2013  - 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 228: #pragma conf 2013  - 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 229: #pragma conf 2013  - 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 230: #pragma conf 2013  - UIKit dynamics

UIDynamicItem Protocol

•All items animated by UIKit Dynamics must implement this protocol

Page 231: #pragma conf 2013  - 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 232: #pragma conf 2013  - 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 233: #pragma conf 2013  - 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 234: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator Reference view

UIDynamicBehavior UIDynamicBehavior

View View View

UIDynamicBehavior

Page 235: #pragma conf 2013  - UIKit dynamics

Architecture

UIDynamicAnimator Reference view

UIDynamicBehavior UIDynamicBehaviorUIDynamicBehavior

NSObject!<UIDynamicItem>

NSObject!<UIDynamicItem>

NSObject!<UIDynamicItem>

Page 236: #pragma conf 2013  - 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 237: #pragma conf 2013  - 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 238: #pragma conf 2013  - 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 239: #pragma conf 2013  - 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 240: #pragma conf 2013  - 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 241: #pragma conf 2013  - 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 242: #pragma conf 2013  - 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 243: #pragma conf 2013  - 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 244: #pragma conf 2013  - 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 245: #pragma conf 2013  - 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 246: #pragma conf 2013  - 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 247: #pragma conf 2013  - 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 248: #pragma conf 2013  - UIKit dynamics

Example 1: conform to UIDynamicItem

Page 249: #pragma conf 2013  - 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 250: #pragma conf 2013  - 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 251: #pragma conf 2013  - UIKit dynamics

•Can use a single dynamic item to animate different views

UIDynamicItem Use Case

Page 252: #pragma conf 2013  - UIKit dynamics

•Can use a single dynamic item to animate different views

•Can map center or transform to something else

UIDynamicItem Use Case

Page 253: #pragma conf 2013  - UIKit dynamics

•Can use a single dynamic item to animate different views

•Can map center or transform to something else

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

UIDynamicItem Use Case

Page 254: #pragma conf 2013  - UIKit dynamics

•Can use a single dynamic item to animate different views

•Can map center or transform to something else

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

UIDynamicItem Use Case

Page 255: #pragma conf 2013  - UIKit dynamics

Example 2: remap center property

Page 256: #pragma conf 2013  - 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 257: #pragma conf 2013  - 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 258: #pragma conf 2013  - 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 259: #pragma conf 2013  - 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 260: #pragma conf 2013  - 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 261: #pragma conf 2013  - 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 262: #pragma conf 2013  - 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 263: #pragma conf 2013  - 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 264: #pragma conf 2013  - 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 265: #pragma conf 2013  - 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 266: #pragma conf 2013  - 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 267: #pragma conf 2013  - 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 268: #pragma conf 2013  - 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 269: #pragma conf 2013  - 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 270: #pragma conf 2013  - 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 271: #pragma conf 2013  - 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 272: #pragma conf 2013  - UIKit dynamics

Example 2: remap center property

Page 273: #pragma conf 2013  - 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 274: #pragma conf 2013  - 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 275: #pragma conf 2013  - 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 276: #pragma conf 2013  - 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 277: #pragma conf 2013  - 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 278: #pragma conf 2013  - 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 279: #pragma conf 2013  - UIKit dynamics

Dynamics & Collection View

Page 280: #pragma conf 2013  - UIKit dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

Page 281: #pragma conf 2013  - UIKit dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

Page 282: #pragma conf 2013  - UIKit dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

• How

Page 283: #pragma conf 2013  - UIKit dynamics

Dynamics & UICollectionViews

• UICollectionViewLayoutAttributes conform to UIDynamicItem

•Can use UIKit Dynamics with collection view

• How

•Use UIKit Dynamics for very specific animations

Page 284: #pragma conf 2013  - 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 285: #pragma conf 2013  - 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 286: #pragma conf 2013  - 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 287: #pragma conf 2013  - 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 288: #pragma conf 2013  - UIKit dynamics

Basic steps

•Create the the UICollectionViewLayout instance

Page 289: #pragma conf 2013  - UIKit dynamics

Basic steps

•Create the the UICollectionViewLayout instance

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

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

Page 290: #pragma conf 2013  - UIKit dynamics

Basic steps

•Create the the UICollectionViewLayout instance

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

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

Page 291: #pragma conf 2013  - UIKit dynamics

Basic steps

•Create the the UICollectionViewLayout instance

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

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

Page 292: #pragma conf 2013  - UIKit dynamics

Basic steps

•Create the the UICollectionViewLayout instance

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

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

Page 293: #pragma conf 2013  - 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 294: #pragma conf 2013  - 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 295: #pragma conf 2013  - 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 296: #pragma conf 2013  - 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 297: #pragma conf 2013  - UIKit dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

Page 298: #pragma conf 2013  - UIKit dynamics

UIKit Dynamics Support for UICollectionViews

Dynamics has convenience support for UICollectionView

•Dynamics automatically invalidate layout as needed

Page 299: #pragma conf 2013  - 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 300: #pragma conf 2013  - 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 convenience method to implement custom layout

Page 301: #pragma conf 2013  - 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 convenience method to implement custom layout- (UICollectionViewLayoutAttributes*)layoutAttributesForCellAtIndexPath:(NSIndexPath*)ip;

Page 302: #pragma conf 2013  - 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 convenience method to implement custom layout- (UICollectionViewLayoutAttributes*)layoutAttributesForCellAtIndexPath:(NSIndexPath*)ip;

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

Page 303: #pragma conf 2013  - 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 convenience method to implement custom layout- (UICollectionViewLayoutAttributes*)layoutAttributesForCellAtIndexPath:(NSIndexPath*)ip;

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

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

Page 304: #pragma conf 2013  - UIKit dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: 

Page 305: #pragma conf 2013  - UIKit dynamics

Collection View Layout Updates

Use usual UICollectionViewLayout methods for layout update: • prepareLayout

Page 306: #pragma conf 2013  - UIKit dynamics

Collection View Layout Updates

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

Page 307: #pragma conf 2013  - 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 308: #pragma conf 2013  - 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 309: #pragma conf 2013  - 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 310: #pragma conf 2013  - 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 311: #pragma conf 2013  - UIKit dynamics

Example: collection view

Page 312: #pragma conf 2013  - 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 313: #pragma conf 2013  - 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 314: #pragma conf 2013  - 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 315: #pragma conf 2013  - 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 316: #pragma conf 2013  - 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 317: #pragma conf 2013  - 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 318: #pragma conf 2013  - 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 319: #pragma conf 2013  - 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 320: #pragma conf 2013  - 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 321: #pragma conf 2013  - 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 322: #pragma conf 2013  - 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 323: #pragma conf 2013  - 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 324: #pragma conf 2013  - 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 325: #pragma conf 2013  - 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 326: #pragma conf 2013  - 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 327: #pragma conf 2013  - 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 328: #pragma conf 2013  - 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 329: #pragma conf 2013  - 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 330: #pragma conf 2013  - 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 331: #pragma conf 2013  - 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 332: #pragma conf 2013  - 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 333: #pragma conf 2013  - 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 334: #pragma conf 2013  - 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 335: #pragma conf 2013  - 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 336: #pragma conf 2013  - 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 337: #pragma conf 2013  - 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 338: #pragma conf 2013  - 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 339: #pragma conf 2013  - 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 340: #pragma conf 2013  - 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 341: #pragma conf 2013  - 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 342: #pragma conf 2013  - 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 343: #pragma conf 2013  - UIKit dynamics

Conclusion

Page 344: #pragma conf 2013  - UIKit dynamics

Long Story Short

• Identify the type of dynamic items you want to animate

Page 345: #pragma conf 2013  - UIKit dynamics

Long Story Short

• Identify the type of dynamic items you want to animate

•Define container or reference view

Page 346: #pragma conf 2013  - UIKit dynamics

Long Story Short

• Identify the type of dynamic items you want to animate

•Define container or reference view

•Create the behaviours

Page 347: #pragma conf 2013  - 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 348: #pragma conf 2013  - 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 349: #pragma conf 2013  - UIKit dynamics

Tips

•Build iteratively

Page 350: #pragma conf 2013  - UIKit dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

Page 351: #pragma conf 2013  - UIKit dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

Page 352: #pragma conf 2013  - UIKit dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

Page 353: #pragma conf 2013  - UIKit dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

•Collision only for rectangle objects

Page 354: #pragma conf 2013  - UIKit dynamics

Tips

•Build iteratively

•Check for setup which don’t have solutions

•Collision only for rectangle objects

Page 355: #pragma conf 2013  - 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 356: #pragma conf 2013  - 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 357: #pragma conf 2013  - 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 358: #pragma conf 2013  - 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 359: #pragma conf 2013  - UIKit dynamics

Animations and Interactions

•Can combine all previous techniques

Page 360: #pragma conf 2013  - UIKit dynamics

Animations and Interactions

•Can combine all previous techniques

•Core Animation

Page 361: #pragma conf 2013  - 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 362: #pragma conf 2013  - 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 363: #pragma conf 2013  - 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 364: #pragma conf 2013  - UIKit dynamics

Endings

"With great power comes great responsibility."

Francois-Marie Arouet aka Voltaire

Page 365: #pragma conf 2013  - 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 366: #pragma conf 2013  - 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 367: #pragma conf 2013  - UIKit dynamics

Q & A

Page 368: #pragma conf 2013  - UIKit dynamics

THANKS