UIKit Dynamics

34
UIKit Dynamics Craig VanderZwaag @bHCraigV [email protected] Tuesday, October 15, 13

description

A short presentation on UIKit Dynamics for the SLO Cocoaheads group

Transcript of UIKit Dynamics

Page 1: UIKit Dynamics

UIKit Dynamics

Craig VanderZwaag

@[email protected]

Tuesday, October 15, 13

Page 2: UIKit Dynamics

ADD DEPTHAND GRAVITY

AND WEIGHTAND DELIGHT!

Tuesday, October 15, 13

Page 3: UIKit Dynamics

UIKIT DYNAMICS

•New in iOS7 SDK

•Brings real-world physics and interaction behaviors to your apps

•2-Dimensional animations and interaction

Tuesday, October 15, 13

Page 4: UIKit Dynamics

DEMO

Tuesday, October 15, 13

Page 5: UIKit Dynamics

HOW?

• Integrated physics engine and animator

•PhysicsKit- Shared with the new Sprite Kit framework

•Based on Box 2D http://box2d.org

Tuesday, October 15, 13

Page 6: UIKit Dynamics

CONCEPTS

•Dynamic Items

•Dynamic Behaviors

•Dynamic Animators

Tuesday, October 15, 13

Page 7: UIKit Dynamics

DYNAMIC ITEMS

•Objects that can be animated

•Minimal set of geometry properties

•Don’t necessarily have to be views or even on screen

Tuesday, October 15, 13

Page 8: UIKit Dynamics

DYNAMIC BEHAVIORS

• Encapsulate a set of “physical” attributes and behaviors

•Associated to dynamic items to impart them with behaviors

•Gravity, Collision, Friction

•Resistance, Velocity, Attachment

•Can Be composed in a hierarchy

Tuesday, October 15, 13

Page 9: UIKit Dynamics

DYNAMIC ANIMATOR

•Coordinates the dynamic items and behaviors in a view

•Updates the “scene” with each step of the animation

•Holds all the behaviors that describe how dynamic items react

Tuesday, October 15, 13

Page 10: UIKit Dynamics

CODE����������� ������������������  TIME

Tuesday, October 15, 13

Page 11: UIKit Dynamics

STEP ONE:CREATE A DYNAMIC ITEM

@protocol UIDynamicItem <NSObject>

@property (nonatomic, readwrite) CGPoint center;@property (nonatomic, readonly) CGRect bounds;@property (nonatomic, readwrite) CGAffineTransform transform;

@end

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIView : UIResponder<NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem> {

Tuesday, October 15, 13

Page 12: UIKit Dynamics

STEP ONE:CREATE A DYNAMIC ITEM

- (void)viewDidLoad{ [super viewDidLoad]; CGRect frame = {CGPointZero, {100.0, 100.0}}; self.button = [[UIButton alloc] initWithFrame:frame]; self.button.backgroundColor = [UIColor purpleColor]; [self.view addSubview:self.button]; ... }

Tuesday, October 15, 13

Page 13: UIKit Dynamics

STEP TWO:CREATE A DYNAMIC ANIMATOR

NS_CLASS_AVAILABLE_IOS(7_0) @interface UIDynamicAnimator: NSObject

- (instancetype)initWithReferenceView:(UIView*)view;

- (void)addBehavior:(UIDynamicBehavior *)behavior;- (void)removeBehavior:(UIDynamicBehavior *)behavior;- (void)removeAllBehaviors;

@property (nonatomic, readonly) UIView* referenceView;@property (nonatomic, readonly, copy) NSArray* behaviors;

Tuesday, October 15, 13

Page 14: UIKit Dynamics

STEP TWO:CREATE A DYNAMIC ANIMATOR

@implementation ViewController

- (void)viewDidLoad{

...

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

...

}

Tuesday, October 15, 13

Page 15: UIKit Dynamics

STEP THREE:ADD BEHAVIORS

NS_CLASS_AVAILABLE_IOS(7_0) @interface UIDynamicBehavior : NSObject

- (void)addChildBehavior:(UIDynamicBehavior *)behavior;- (void)removeChildBehavior:(UIDynamicBehavior *)behavior;

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

// When running, the dynamic animator calls the action block on every animation step.@property (nonatomic,copy) void (^action)(void);

- (void)willMoveToAnimator:(UIDynamicAnimator *)dynamicAnimator; // nil when being removed from an animator

@property (nonatomic, readonly) UIDynamicAnimator *dynamicAnimator;

@end

Tuesday, October 15, 13

Page 16: UIKit Dynamics

STEP THREE:ADD BEHAVIORS- GRAVITY

NS_CLASS_AVAILABLE_IOS(7_0) @interface UIGravityBehavior : UIDynamicBehavior

- (instancetype)initWithItems:(NSArray *)items;

- (void)addItem:(id <UIDynamicItem>)item;- (void)removeItem:(id <UIDynamicItem>)item;@property (nonatomic, readonly, copy) NSArray* items;

// The default value for the gravity vector is (0.0, 1.0)// The acceleration for a dynamic item subject to a (0.0, 1.0) gravity vector is downwards at 1000 points per second².@property (readwrite, nonatomic) CGVector gravityDirection;

@property (readwrite, nonatomic) CGFloat angle;@property (readwrite, nonatomic) CGFloat magnitude;- (void)setAngle:(CGFloat)angle magnitude:(CGFloat)magnitude;

@end

Tuesday, October 15, 13

Page 17: UIKit Dynamics

STEP THREE:ADD BEHAVIORS- GRAVITY

- (void)viewDidLoad{ [super viewDidLoad]; ... UIGravityBehavior* gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.button]]; [self.animator addBehavior:gravityBehavior]; ... }

Tuesday, October 15, 13

Page 18: UIKit Dynamics

TO����������� ������������������  XCODE����������� ������������������  WE����������� ������������������  GO

https://bitbucket.org/craigvz/dynamicssampler

Tuesday, October 15, 13

Page 19: UIKit Dynamics

Tuesday, October 15, 13

Page 20: UIKit Dynamics

WHAT HAPPENED?

Tuesday, October 15, 13

Page 21: UIKit Dynamics

•We fell through the floor

•Button needs to collide with the edge of our view to stay on the screen

Tuesday, October 15, 13

Page 22: UIKit Dynamics

STEP FOUR:ADD BEHAVIORS- COLLISION

NS_CLASS_AVAILABLE_IOS(7_0) @interface UICollisionBehavior : UIDynamicBehavior

- (instancetype)initWithItems:(NSArray *)items;

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

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

@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;...@end

Tuesday, October 15, 13

Page 23: UIKit Dynamics

STEP FOUR:ADD BEHAVIORS- COLLISION

- (void)viewDidLoad{ [super viewDidLoad];

...

UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.button]]; collisionBehavior.collisionMode = UICollisionBehaviorModeBoundaries; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; [self.animator addBehavior:collisionBehavior];

... }

Tuesday, October 15, 13

Page 24: UIKit Dynamics

STEP FIVE:ADD BEHAVIORS- PUSH

NS_CLASS_AVAILABLE_IOS(7_0) @interface UIPushBehavior : UIDynamicBehavior

- (instancetype)initWithItems:(NSArray *)items mode:(UIPushBehaviorMode)mode;

- (void)addItem:(id <UIDynamicItem>)item;- (void)removeItem:(id <UIDynamicItem>)item;@property (nonatomic, readonly, copy) NSArray* items;

- (UIOffset)targetOffsetFromCenterForItem:(id <UIDynamicItem>)item;- (void)setTargetOffsetFromCenter:(UIOffset)o forItem:(id <UIDynamicItem>)item;

@property (nonatomic, readonly) UIPushBehaviorMode mode;@property (nonatomic, readwrite) BOOL active;

@property (readwrite, nonatomic) CGFloat angle;// A continuous force vector with a magnitude of 1.0, applied to a 100 point x 100 point view whose density value is 1.0, results in view acceleration of 100 points per s^2@property (readwrite, nonatomic) CGFloat magnitude;@property (readwrite, nonatomic) CGVector pushDirection;

- (void)setAngle:(CGFloat)angle magnitude:(CGFloat)magnitude;

@end

Tuesday, October 15, 13

Page 25: UIKit Dynamics

STEP FIVE:ADD BEHAVIORS- PUSH

- (void)viewDidLoad{

...

self.pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.button] mode:UIPushBehaviorModeInstantaneous]; CGFloat magnitude = 20.0; [self.pushBehavior setAngle:-M_PI_2 magnitude:magnitude]; self.pushBehavior.active = NO; [self.animator addBehavior:self.pushBehavior];

...}

Tuesday, October 15, 13

Page 26: UIKit Dynamics

STEP SIX:TWEAK ITEM PROPERTIES

NS_CLASS_AVAILABLE_IOS(7_0) @interface UIDynamicItemBehavior : UIDynamicBehavior

...

@property (readwrite, nonatomic) CGFloat elasticity; // Usually between 0 (inelastic) and 1 (collide elastically) @property (readwrite, nonatomic) CGFloat friction; // 0 being no friction between objects slide along each other@property (readwrite, nonatomic) CGFloat density; // 1 by default@property (readwrite, nonatomic) CGFloat resistance; // 0: no velocity damping@property (readwrite, nonatomic) CGFloat angularResistance; // 0: no angular velocity damping@property (readwrite, nonatomic) BOOL allowsRotation; // force an item to never rotate

...

@end

Tuesday, October 15, 13

Page 27: UIKit Dynamics

STEP SIX:TWEAK ITEM PROPERTIES

NS_CLASS_AVAILABLE_IOS(7_0) @interface UIDynamicItemBehavior : UIDynamicBehavior

...

// The linear velocity, expressed in points per second, that you want to add to the specified dynamic item// If called before being associated to an animator, the behavior will accumulate values until being associated to an animator- (void)addLinearVelocity:(CGPoint)velocity forItem:(id <UIDynamicItem>)item;- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;

// The angular velocity, expressed in radians per second, that you want to add to the specified dynamic item// If called before being associated to an animator, the behavior will accumulate values until being associated to an animator- (void)addAngularVelocity:(CGFloat)velocity forItem:(id <UIDynamicItem>)item;- (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;

@end

Tuesday, October 15, 13

Page 28: UIKit Dynamics

STEP SIX:TWEAK ITEM PROPERTIES

- (void)viewDidLoad{ [super viewDidLoad];

...

UIDynamicItemBehavior* dynamicItemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.button]]; dynamicItemBehavior.elasticity = 0.5; dynamicItemBehavior.resistance = 1.0;

...

}

Tuesday, October 15, 13

Page 29: UIKit Dynamics

UNITS

Tuesday, October 15, 13

Page 30: UIKit Dynamics

UNITS

•Many properties have their own unit of measure

• UIGravityBehavior’s magnitude:

• 1.0 = 1000 points / second2

• UIPushBehavior magnitude:

• 1.0 = 100 points / second2 for 100 point x 100 point item with density = 1.0 (UIKit Newton)

Tuesday, October 15, 13

Page 31: UIKit Dynamics

DELEGATES

@protocol UIDynamicAnimatorDelegate <NSObject>

@optional- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator;- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator;

@end

Tuesday, October 15, 13

Page 32: UIKit Dynamics

DELEGATES@protocol UICollisionBehaviorDelegate <NSObject>@optional

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

// The identifier of a boundary created with translatesReferenceBoundsIntoBoundary or setTranslatesReferenceBoundsIntoBoundaryWithInsets is nil- (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;

@end

Tuesday, October 15, 13

Page 33: UIKit Dynamics

Tuesday, October 15, 13

Page 34: UIKit Dynamics

THE����������� ������������������  END!

@[email protected]

Tuesday, October 15, 13