UIKit Dynamics

Preview:

DESCRIPTION

A short presentation on UIKit Dynamics for the SLO Cocoaheads group

Citation preview

UIKit Dynamics

Craig VanderZwaag

@bHCraigVcraig@bluehulastudios.com

Tuesday, October 15, 13

ADD DEPTHAND GRAVITY

AND WEIGHTAND DELIGHT!

Tuesday, October 15, 13

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

DEMO

Tuesday, October 15, 13

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

CONCEPTS

•Dynamic Items

•Dynamic Behaviors

•Dynamic Animators

Tuesday, October 15, 13

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

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

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

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

Tuesday, October 15, 13

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

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

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

STEP TWO:CREATE A DYNAMIC ANIMATOR

@implementation ViewController

- (void)viewDidLoad{

...

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

...

}

Tuesday, October 15, 13

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

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

STEP THREE:ADD BEHAVIORS- GRAVITY

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

Tuesday, October 15, 13

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

https://bitbucket.org/craigvz/dynamicssampler

Tuesday, October 15, 13

Tuesday, October 15, 13

WHAT HAPPENED?

Tuesday, October 15, 13

•We fell through the floor

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

Tuesday, October 15, 13

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

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

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

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

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

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

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

UNITS

Tuesday, October 15, 13

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

DELEGATES

@protocol UIDynamicAnimatorDelegate <NSObject>

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

@end

Tuesday, October 15, 13

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

Tuesday, October 15, 13

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

@bHCraigVcraig@bluehulastudios.com

Tuesday, October 15, 13

Recommended