More Related Content Similar to Hackatron - UIKit Dynamics Similar to Hackatron - UIKit Dynamics (20) Hackatron - UIKit Dynamics4. About me
Renzo
iOS Developer
H-art
!
#pragma mark founder
renzo.pretto@pragmamark.org
!
@rgpretto
14. Statuto
L’associazione senza fini di lucro #pragma mark ha lo
scopo di svolgere attività di “community of practice, ovvero
di condivisione delle conoscenze ed esperienze tra persone
la cui professionalità ruota intorno le tecnologie
informatiche e iOS in particolare, fornendo un nuovo
modello per connetterle nello spirito dell’apprendimento,
della conoscenza condivisa e della collaborazione sia come
individui sia come gruppi”
29. Today Agenda
• Introduction and core concepts
• Standard effects: dynamic behaviors
• Custom effects: custom behaviors
• Advanced concepts
30. Today Agenda
• Introduction and core concepts
• Standard effects: dynamic behaviors
• Custom effects: custom behaviors
• Advanced concepts
• UIDynamicItem
31. Today Agenda
• Introduction and core concepts
• Standard effects: dynamic behaviors
• Custom effects: custom behaviors
• Advanced concepts
• UIDynamicItem
• Collection View
32. Today Agenda
• Introduction and core concepts
• Standard effects: dynamic behaviors
• Custom effects: custom behaviors
• Advanced concepts
• UIDynamicItem
• Collection View
• Conclusion
47. UIDynamicAnimator
• Define the coordinate system
• Wraps underline engine
• Keeps track of all the associated behaviors
UIDynamicAnimator
Reference view
48. UIDynamicAnimator
• Define the coordinate system
• Wraps underline engine
• Keeps track of all the associated behaviors
• Run and optimize the animation
UIDynamicAnimator
Reference view
49. UIDynamicAnimator
• Define the coordinate system
UIDynamicAnimator
• Wraps underline engine
• Keeps track of all the associated behaviors
Reference view
• Run and optimize the animation
• Each dynamic animator is independent from other dynamic
animators
50. UIDynamicAnimator
• Define the coordinate system
UIDynamicAnimator
• Wraps underline engine
• Keeps track of all the associated behaviors
Reference view
• 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];
...
51. UIDynamicAnimator
• Define the coordinate system
UIDynamicAnimator
• Wraps underline engine
• Keeps track of all the associated behaviors
Reference view
• 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];
...
52. UIDynamicAnimator
• Define the coordinate system
UIDynamicAnimator
• Wraps underline engine
• Keeps track of all the associated behaviors
Reference view
• 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];
...
53. UIDynamicAnimator
• Define the coordinate system
UIDynamicAnimator
• Wraps underline engine
• Keeps track of all the associated behaviors
Reference view
• 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];
...
64. Behaviors Common characteristics
• Initialised with items to animate
• Items can be added to behavior at any times
• Behaviour can be configured before or after add to an
animator
65. Behaviors Common characteristics
• Initialised with items to animate
• Items can be added to behavior at any times
• Behaviour can be configured before or after add to an
animator
• Behavior influence stops when behaviour is removed
77. UIGravityBehavior
@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
78. UIGravityBehavior
@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
79. UIGravityBehavior
@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
80. UIGravityBehavior
@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
81. UIGravityBehavior
@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
83. UIGravityBehavior
• Defined by a gravity vector
@property (readwrite, nonatomic) CGVector gravityDirection;
or
@property (readwrite, nonatomic) CGFloat angle;
@property (readwrite, nonatomic) CGFloat magnitude;
84. 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)
85. 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)
86. 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
- (void)addItem:(id <UIDynamicItem>)item;
- (void)removeItem:(id <UIDynamicItem>)item;
(0.0, 1.0)
89. UICollisionBehavior
@interface DPCollisionsViewController : UIViewController
@property (strong, nonatomic) UIDynamicAnimator *animator;
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
!
@implementation DPGravityCollisionViewController
...
- (void)viewDidLoad {
[super viewDidLoad];
!
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
NSArray *items = @[self.greenView];
!
UICollisionBehavior *collisionBehavior;
collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
UIGravityBehavior *gravityBehavior;
gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items];
}
...
@end
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:gravityBehavior];
90. UICollisionBehavior
@interface DPCollisionsViewController : UIViewController
@property (strong, nonatomic) UIDynamicAnimator *animator;
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
!
@implementation DPGravityCollisionViewController
...
- (void)viewDidLoad {
[super viewDidLoad];
!
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
NSArray *items = @[self.greenView];
!
UICollisionBehavior *collisionBehavior;
collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
UIGravityBehavior *gravityBehavior;
gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items];
}
...
@end
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:gravityBehavior];
91. UICollisionBehavior
@interface DPCollisionsViewController : UIViewController
@property (strong, nonatomic) UIDynamicAnimator *animator;
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
!
@implementation DPGravityCollisionViewController
...
- (void)viewDidLoad {
[super viewDidLoad];
!
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
NSArray *items = @[self.greenView];
!
UICollisionBehavior *collisionBehavior;
collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
UIGravityBehavior *gravityBehavior;
gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items];
}
...
@end
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:gravityBehavior];
92. UICollisionBehavior
@interface DPCollisionsViewController : UIViewController
@property (strong, nonatomic) UIDynamicAnimator *animator;
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
!
@implementation DPGravityCollisionViewController
...
- (void)viewDidLoad {
[super viewDidLoad];
!
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
NSArray *items = @[self.greenView];
!
UICollisionBehavior *collisionBehavior;
collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
UIGravityBehavior *gravityBehavior;
gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items];
}
...
@end
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:gravityBehavior];
93. UICollisionBehavior
@interface DPCollisionsViewController : UIViewController
@property (strong, nonatomic) UIDynamicAnimator *animator;
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
!
@implementation DPGravityCollisionViewController
...
- (void)viewDidLoad {
[super viewDidLoad];
!
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
NSArray *items = @[self.greenView];
!
UICollisionBehavior *collisionBehavior;
collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
UIGravityBehavior *gravityBehavior;
gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items];
}
...
@end
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:gravityBehavior];
94. UICollisionBehavior
@interface DPCollisionsViewController : UIViewController
@property (strong, nonatomic) UIDynamicAnimator *animator;
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
!
@implementation DPGravityCollisionViewController
...
- (void)viewDidLoad {
[super viewDidLoad];
!
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
NSArray *items = @[self.greenView];
!
UICollisionBehavior *collisionBehavior;
collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
UIGravityBehavior *gravityBehavior;
gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items];
}
...
@end
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:gravityBehavior];
95. UICollisionBehavior
@interface DPCollisionsViewController : UIViewController
@property (strong, nonatomic) UIDynamicAnimator *animator;
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
!
@implementation DPGravityCollisionViewController
...
- (void)viewDidLoad {
[super viewDidLoad];
!
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
NSArray *items = @[self.greenView];
!
UICollisionBehavior *collisionBehavior;
collisionBehavior = [[UICollisionBehavior alloc] initWithItems:items];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
UIGravityBehavior *gravityBehavior;
gravityBehavior =[[UIGravityBehavior alloc] initWithItems:items];
}
...
@end
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:gravityBehavior];
97. Collision Boundaries
• Can specify different boundaries
• Reference view
@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;
98. Collision Boundaries
• Can specify different boundaries
• Reference view
@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;
• Insets to reference view
- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;
99. 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;
100. 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;
101. 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;
102. 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
105. Collision Mode
• Property collisionmode
@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;
• UICollisionBehaviorModeBoundaries
106. Collision Mode
• Property collisionmode
@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;
• UICollisionBehaviorModeBoundaries
• UICollisionBehaviorModeItems
107. Collision Mode
• Property collisionmode
@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;
• UICollisionBehaviorModeBoundaries
• UICollisionBehaviorModeItems
• UICollisionBehaviorModeEverything
(default)
109. Tips
• Can use multiple collision behaviors
• Add and remove items to this behaviour anytime
- (void)addItem:(id <UIDynamicItem>)item;
- (void)removeItem:(id <UIDynamicItem>)item;
110. Tips
• Can use multiple collision behaviors
• Add and remove items to this behaviour anytime
- (void)addItem:(id <UIDynamicItem>)item;
- (void)removeItem:(id <UIDynamicItem>)item;
• Collision detection have CPU cost
112. UICollisionBehaviorDelegate
• 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;
113. UICollisionBehaviorDelegate
• 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
114. UICollisionBehaviorDelegate
• 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;
115. UICollisionBehaviorDelegate
• 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;
116. UICollisionBehaviorDelegate
• 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
119. 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
120. 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
121. 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
122. 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
123. 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
124. 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
128. UIAttachmentBehavior
• 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;
129. UIAttachmentBehavior
• 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
130. UIAttachmentBehavior
• 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;
131. UIAttachmentBehavior
• 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;
138. UISnapBehavior
interface 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
139. UISnapBehavior
interface 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
140. UISnapBehavior
interface 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
141. UISnapBehavior
interface 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
142. UISnapBehavior
interface 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
143. UISnapBehavior
interface 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
145. UISnapBehavior
• Snap view in place in non rotated state
- (instancetype)initWithItem:(id <UIDynamicItem>)item
snapToPoint:(CGPoint)point;
146. UISnapBehavior
• Snap view in place in non rotated state
- (instancetype)initWithItem:(id <UIDynamicItem>)item
snapToPoint:(CGPoint)point;
• Customize the dumping effects
147. 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;
151. UIPushBehavior
~
F = m ~ , apply force to views:
a
•
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
152. UIPushBehavior
~
F = m ~ , apply force to views:
a
•
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• Force vector expressed in two way:
153. UIPushBehavior
~
F = m ~ , apply force to views:
a
•
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• Force vector expressed in two way:
@property (readwrite, nonatomic) CGVector pushDirection;
154. UIPushBehavior
~
F = m ~ , apply force to views:
a
•
- (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;
160. 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
161. 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;
162. 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;
163. 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;
165. UIPushBehavior Mode
• Different mode to apply forces:
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• UIPushBehaviorModeContinuous
166. UIPushBehavior Mode
• Different mode to apply forces:
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• UIPushBehaviorModeContinuous
• force still be applied while behaviour is active
167. UIPushBehavior Mode
• Different mode to apply forces:
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• UIPushBehaviorModeContinuous
• force still be applied while behaviour is active
• views accelerate
168. UIPushBehavior Mode
• Different mode to apply forces:
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• UIPushBehaviorModeContinuous
• force still be applied while behaviour is active
• views accelerate
•UIPushBehaviorModeInstantaneous
169. UIPushBehavior Mode
• Different mode to apply forces:
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• UIPushBehaviorModeContinuous
• force still be applied while behaviour is active
• views accelerate
•UIPushBehaviorModeInstantaneous
• apply a very quick impulse
170. UIPushBehavior Mode
• Different mode to apply forces:
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• UIPushBehaviorModeContinuous
• force still be applied while behaviour is active
• views accelerate
•UIPushBehaviorModeInstantaneous
• apply a very quick impulse
• view immediately acquire velocity (no acceleration)
171. UIPushBehavior Mode
• Different mode to apply forces:
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• UIPushBehaviorModeContinuous
• force still be applied while behaviour is active
• views accelerate
•UIPushBehaviorModeInstantaneous
• apply a very quick impulse
• view immediately acquire velocity (no acceleration)
•
automatically disable itself after applying it
172. UIPushBehavior Mode
• Different mode to apply forces:
- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;
• UIPushBehaviorModeContinuous
• force still be applied while behaviour is active
• views accelerate
•UIPushBehaviorModeInstantaneous
• apply a very quick impulse
• view immediately acquire velocity (no acceleration)
•
automatically disable itself after applying it
• to re-enable: @property
(nonatomic, readwrite) BOOL active;
179. Feel The Force!
• Gravity
• views accelerate with the same rate
• Push behavior in continuos mode
180. Feel The Force!
• Gravity
• views accelerate with the same rate
• Push behavior in continuos mode
• the smaller views accelerate more
181. 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
182. 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
183. 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
185. Unit of Measure
• Real world: Newton
1 Newton accelerate 1Kg at a rate of 1 m/s2
•
186. 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
187. 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”
192. UIDynamicItemBehavior
• Customize dynamics properties for items
@property (readwrite, nonatomic) CGFloat elasticity;
@property (readwrite, nonatomic) CGFloat friction;
@property (readwrite, nonatomic) CGFloat density;
193. UIDynamicItemBehavior
• Customize dynamics properties for items
@property
@property
@property
@property
(readwrite,
(readwrite,
(readwrite,
(readwrite,
nonatomic)
nonatomic)
nonatomic)
nonatomic)
CGFloat
CGFloat
CGFloat
CGFloat
elasticity;
friction;
density;
resistance;
194. UIDynamicItemBehavior
• Customize dynamics properties for items
@property
@property
@property
@property
@property
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
CGFloat
CGFloat
CGFloat
CGFloat
CGFloat
elasticity;
friction;
density;
resistance;
angularResistance;
195. UIDynamicItemBehavior
• Customize dynamics properties for items
@property
@property
@property
@property
@property
@property
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
CGFloat elasticity;
CGFloat friction;
CGFloat density;
CGFloat resistance;
CGFloat angularResistance;
BOOL allowsRotation;
196. UIDynamicItemBehavior
• Customize dynamics properties for items
@property
@property
@property
@property
@property
@property
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
CGFloat elasticity;
CGFloat friction;
CGFloat density;
CGFloat resistance;
CGFloat angularResistance;
BOOL allowsRotation;
• Add linear velocity (points per second)
- (void)addLinearVelocity:(CGPoint)velocity
forItem:(id <UIDynamicItem>)item;
- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;
197. UIDynamicItemBehavior
• Customize dynamics properties for items
@property
@property
@property
@property
@property
@property
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
CGFloat elasticity;
CGFloat friction;
CGFloat density;
CGFloat resistance;
CGFloat angularResistance;
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;
198. UIDynamicItemBehavior
• Customize dynamics properties for items
@property
@property
@property
@property
@property
@property
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
CGFloat elasticity;
CGFloat friction;
CGFloat density;
CGFloat resistance;
CGFloat angularResistance;
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
199. UIDynamicItemBehavior
• Customize dynamics properties for items
@property
@property
@property
@property
@property
@property
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
CGFloat elasticity;
CGFloat friction;
CGFloat density;
CGFloat resistance;
CGFloat angularResistance;
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
200. UIDynamicItemBehavior
• Customize dynamics properties for items
@property
@property
@property
@property
@property
@property
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
(readwrite,
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
nonatomic)
CGFloat elasticity;
CGFloat friction;
CGFloat density;
CGFloat resistance;
CGFloat angularResistance;
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
202. Long Story Short
• Identify the type of dynamic items you want to animate
• Define container or reference view
203. Long Story Short
• Identify the type of dynamic items you want to animate
• Define container or reference view
• Create the behaviours
204. 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
205. 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
208. Custom Behavior
• Can subclass UIDynamicBehavior
• add child behavior
- (void)addChildBehavior:(UIDynamicBehavior *)behavior;
- (void)removeChildBehavior:(UIDynamicBehavior *)behavior;
@property (nonatomic, readonly, copy) NSArray* childBehaviors;
209. 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
211. 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
212. 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
213. 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
214. 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
215. 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
216. Example: gravity & collision
@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
217. Example: gravity & collision
@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
218. Example: gravity & collision
@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
219. Example: gravity & collision
@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
220. Example: gravity & collision
@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
221. Example: gravity & collision
@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
222. Example: gravity & collision
@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
223. Example: gravity & collision
@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
224. Example: gravity & collision
@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
225. 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
226. 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 = @[...];
DPGravityCollisionBehavior *gravityAndCollision;
gravityAndCollision= [[DPGravityCollisionBehavior alloc] initWithItems:items];
[self.animator addBehavior:gravityAndCollision];
}
!
@end
228. Action Block
• Can define per-step actions
@property (nonatomic, copy) void (^action)(void);
229. Action Block
• Can define per-step actions
@property (nonatomic, copy) void (^action)(void);
• UIDynamicAnimator invoke this block in each simulation step
230. 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
233. UIDynamicItem Protocol
@protocol UIDynamicItem <NSObject>
!
@property (nonatomic, readwrite) CGPoint center;
@property (nonatomic, readonly) CGRect bounds;
@property (nonatomic, readwrite) CGAffineTransform transform;
!
@end
• All items animated by UIKit Dynamics must implement this
protocol
234. UIDynamicItem Protocol
@protocol UIDynamicItem <NSObject>
!
@property (nonatomic, readwrite) CGPoint center;
@property (nonatomic, readonly) CGRect bounds;
@property (nonatomic, readwrite) CGAffineTransform transform;
!
@end
• All items animated by UIKit Dynamics must implement this
protocol
• Describe what UIKit Dynamics needs to animate an item
235. UIDynamicItem Protocol
@protocol UIDynamicItem <NSObject>
!
@property (nonatomic, readwrite) CGPoint center;
@property (nonatomic, readonly) CGRect bounds;
@property (nonatomic, readwrite) CGAffineTransform transform;
!
@end
• All items animated by UIKit Dynamics must implement this
protocol
• Describe what UIKit Dynamics needs to animate an item
• position: center
236. UIDynamicItem Protocol
@protocol UIDynamicItem <NSObject>
!
@property (nonatomic, readwrite) CGPoint center;
@property (nonatomic, readonly) CGRect bounds;
@property (nonatomic, readwrite) CGAffineTransform transform;
!
@end
• All items animated by UIKit Dynamics must implement this
protocol
• Describe what UIKit Dynamics needs to animate an item
• position: center
• size: bounds
237. UIDynamicItem Protocol
@protocol UIDynamicItem <NSObject>
!
@property (nonatomic, readwrite) CGPoint center;
@property (nonatomic, readonly) CGRect bounds;
@property (nonatomic, readwrite) CGAffineTransform transform;
!
@end
• 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)
240. 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
241. 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
242. 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
243. 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
244. 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
245. 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
247. UIDynamicItem Protocol
• All items animated by UIKit Dynamics must implement this
protocol
• UIView conforms to protocol
@interface UIView : UIResponder < NSCoding, UIAppearance,
UIAppearanceContainer, UIDynamicItem > { ... }
248. 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 > { ... }
249. 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 > { ... }
252. Example 1: conform to UIDynamicItem
@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
253. Example 1: conform to UIDynamicItem
@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
254. Example 1: conform to UIDynamicItem
@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
255. Example 1: conform to UIDynamicItem
@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
256. Example 1: conform to UIDynamicItem
@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
257. 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
258. 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
259. 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
260. 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
261. 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
262. 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
263. 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
265. Example 1: conform to UIDynamicItem
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
!
18:58:05.598
18:58:05.609
18:58:05.611
18:58:05.626
18:58:05.629
18:58:05.642
18:58:05.645
18:58:05.659
18:58:05.661
18:58:05.675
18:58:05.677
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
Animator is running
Center = {50, 50.04797}
Transform = [1, 0, -0, 1,
Center = {50, 50.447464}
Transform = [1, 0, -0, 1,
Center = {50, 51.054173}
Transform = [1, 0, -0, 1,
Center = {50, 51.915657}
Transform = [1, 0, -0, 1,
Center = {50, 53.031506}
Transform = [1, 0, -0, 1,
18:58:08.742
18:58:08.744
18:58:08.759
18:58:08.761
18:58:08.775
18:58:08.777
18:58:08.792
18:58:08.794
18:58:08.809
18:58:08.810
18:58:08.812
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Animator is stopped
0, 0]
0, 0]
0, 0]
0, 0]
0, 0]
...
!
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
0, 0]
0, 0]
0, 0]
0, 0]
0, 0]
266. Example 1: conform to UIDynamicItem
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
!
18:58:05.598
18:58:05.609
18:58:05.611
18:58:05.626
18:58:05.629
18:58:05.642
18:58:05.645
18:58:05.659
18:58:05.661
18:58:05.675
18:58:05.677
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
Animator is running
Center = {50, 50.04797}
Transform = [1, 0, -0, 1,
Center = {50, 50.447464}
Transform = [1, 0, -0, 1,
Center = {50, 51.054173}
Transform = [1, 0, -0, 1,
Center = {50, 51.915657}
Transform = [1, 0, -0, 1,
Center = {50, 53.031506}
Transform = [1, 0, -0, 1,
18:58:08.742
18:58:08.744
18:58:08.759
18:58:08.761
18:58:08.775
18:58:08.777
18:58:08.792
18:58:08.794
18:58:08.809
18:58:08.810
18:58:08.812
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
DynamicsPlayground[771:60b]
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Center = {50, 518.13135}
Transform = [1, 0, -0, 1,
Animator is stopped
0, 0]
0, 0]
0, 0]
0, 0]
0, 0]
...
!
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
2013-10-17
0, 0]
0, 0]
0, 0]
0, 0]
0, 0]
268. UIDynamicItem Use Case
• Can use a single dynamic item to animate different views
• Can map center or transform to something else
269. UIDynamicItem Use Case
• Can use a single dynamic item to animate different views
• Can map center or transform to something else
• To “animate” something that isnt’a a view or a collection
view use a UIDynamicItem
270. UIDynamicItem Use Case
• Can use a single dynamic item to animate different views
• Can map center or transform to something else
• To “animate” something that isnt’a a view or a collection
view use a UIDynamicItem
272. 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
273. 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
274. 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
275. 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
276. 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
277. 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
278. 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
279. 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
280. 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