These are confidential sessions—please refrain from streaming, blogging, or taking pictures
Make it so
Session 226
Implementing Engaging UI on iOS
Brandon NewendorpiOS Software Engineer
Jim TurneriOS Software Engineer
Agenda
• Transitions• Custom appearance• Realistic motion
Custom View Controller Transitions
Going beyond animated:YESUIViewController Transitions
• New API to customize view controller transitions• UIViewController present and dismiss• Navigation push/pop• Interactive and non-interactive
toVC = [[PhotoDetailView alloc] init];
toVC = [[PhotoDetailView alloc] init];
toVC.transitioningDelegate = self
toVC.transitioningDelegate = self
presentViewController:toVCanimated:YEScompletion:nil
presentViewController:toVCanimated:YEScompletion:nil
animationControllerForPresentedController:presentingController:sourceController:
animationControllerForPresentedController:presentingController:sourceController:
animationControllerForPresentedController:
animationControllerForPresentedController:presentingController:sourceController:presentingController:
animationControllerForPresentedController:presentingController:sourceController:sourceController:
animationControllerForPresentedController:presentingController:sourceController:
animationControllerForPresentedController:presentingController:sourceController:
id<UIViewControllerAnimatedTransitioning>
transitionDuration:animateTransition:
UIPercentDrivenInteractiveTransitionUIViewController Transitions
• Provided object for interactive transitions• Update the transition based on touch or other input• Vary completionSpeed and completionCurve to change behavior
What it’s good forUISnapshotting
• Improvement on -[CALayer renderInContext:]• Representation of a view’s currently rendered contents• Very fast• Useful in animations• Creating special effects
UISnapshotting
UISnapshotting
renderInContext:
snapshotView:
0 225 450 675 900
145
56
844
Milliseconds (ms)
Faster and betterUISnapshotting
renderInContext:
snapshotView:
0 225 450 675 900
145
56
844
Milliseconds (ms)
844
Faster and betterUISnapshotting
renderInContext:
snapshotView:
0 225 450 675 900
145
56
844
Milliseconds (ms)
844
56
Faster and betterUISnapshotting
APIUISnapshotting
- (UIView *)snapshotView- (UIView *)resizableSnapshotViewFromRect:(CGRect)rect withCapInsets:(UIEdgeInsets)capInsets
APIUISnapshotting
- (UIView *)snapshotView- (UIView *)resizableSnapshotViewFromRect:(CGRect)rect withCapInsets:(UIEdgeInsets)capInsets
- (BOOL)drawViewHierarchyInRect:(CGRect)rect
renderInContext:
snapshotView:
0 225 450 675 900
145
56
844
Milliseconds (ms)
Faster and betterUISnapshotting
56
renderInContext:
snapshotView:
0 225 450 675 900
145
56
844
Milliseconds (ms)
Faster and betterUISnapshotting
drawViewHierarchyInRect:
56
renderInContext:
snapshotView:
0 225 450 675 900
145
56
844
Milliseconds (ms)
145
Faster and betterUISnapshotting
drawViewHierarchyInRect:
56
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Making a Blurred Background
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
[view drawViewHierarchyInRect:rect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lightImage = [newImage applyLightEffect];
Better than everAppearance Customization
[[UISlider appearance] setTintColor:[UIColor redColor]]
[self.window setTintColor:[UIColor redColor]]
UIAppearanceAppearance Customization
+ (instancetype)appearance
+ (instancetype)appearanceWhenContainedIn:
Appearance Customization
+ (instancetype)appearance
+ (instancetype)appearanceWhenContainedIn:
- (UIColor *)tintColor
- (UIColor *)barTintColor
Appearance Customization
- [UIImage imageWithRenderingMode:]
Appearance Customization
- [UIImage imageWithRenderingMode:]
Appearance Customization
- [UIImage imageWithRenderingMode:]
UIImageRenderingModeAutomatic
Appearance Customization
- [UIImage imageWithRenderingMode:]
UIImageRenderingModeAutomatic
UIImageRenderingModeAlwaysOriginal
Appearance Customization
- [UIImage imageWithRenderingMode:]
UIImageRenderingModeAutomatic
UIImageRenderingModeAlwaysOriginal
UIImageRenderingModeAlwaysTemplate
Original image
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate[window setTintColor:[UIColor redColor]];
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate[window setTintColor:[UIColor blueColor]];
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate[window setTintColor:[UIColor blueColor]];
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate[window setTintColor:[UIColor blueColor]];
- [UIImage resizableImageWithCapInsets:]
- [UIImage resizableImageWithCapInsets:]
5pt
5pt 5pt
5pt
- [UIImage resizableImageWithCapInsets:]
5pt
5pt 5pt
5pt
- [UIImage resizableImageWithCapInsets:]
5pt
5pt 5pt
5pt
- [UIImage resizableImageWithCapInsets:]
今日はGuten Tag
5pt
5pt 5pt
5pt
- [UIImage resizableImageWithCapInsets:]
Hello今日はGuten Tag
- [UIImage resizableImageWithCapInsets:]
今日はGuten Tag
- [UIImage resizableImageWithCapInsets:]
Hello今日はGuten Tag
UIKit Dynamics and Motion EffectsRealistic Motion
With great power comes great responsibilityUIKit Dynamics
• Model real world physical behaviors• Not a physics engine• Most effective when used in moderation
The basicsUIKit Dynamics
animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[itemToAnimate]];
[animator addBehavior:gravityBehavior];
The basicsUIKit Dynamics
animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[itemToAnimate]];
[animator addBehavior:gravityBehavior];
The basicsUIKit Dynamics
animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[itemToAnimate]];
[animator addBehavior:gravityBehavior];
The basicsUIKit Dynamics
animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[itemToAnimate]];
[animator addBehavior:gravityBehavior];
UIMotionEffectMotion Effects
• Create effects like the home screen or action sheets
• Device motion is the input• Optimized for power efficiency• Don’t roll your own
Understanding directionsMotion Effects
1-1
-1
1
Understanding directionsMotion Effects
1-1
-1
1
Understanding directionsMotion Effects
1-1
-1
1
Understanding directionsMotion Effects
1-1
-1
1
Understanding directionsMotion Effects
1-1
-1
1
Understanding directionsMotion Effects
1-1
-1
1
UIInterpolatingMotionEffectMotion Effects
• Interpolate between two values• Defined by a key path• Updates based on device motion• Attach UIMotionEffects to a UIView
Advanced behaviorsMotion Effects
UIMotionEffectGroup
Advanced behaviorsMotion Effects
- (NSDictionary *) keyPathsAndRelativeValuesForViewerOffset:(UIOffset)viewerOffset
Wrap Up
• Customize UIViewController transitions• App-wide appearance• Resizable and template images• UIKit Dynamics• UIMotionEffect
Related Sessions
Building User Interfaces for iOS 7 PresidioTuesday 10:15 AM
Customizing Your App’s Appearance for iOS 7 PresidioWednesday 3:15PM
Getting Started with UIKit Dynamics PresidioTuesday 4:30PM
Custom Transitions Using View Controllers Pacific HeightsThursday 11:30 AM
Advanced Techniques with UIKit Dynamics PresidioThursday 3:15PM
More Information
Jake BehrensApp Frameworks [email protected]
DocumentationUIDynamicAnimator Class ReferenceUIPercentDrivenInteractiveTransition Class ReferenceUIAppearance Protocol ReferenceUIViewControllerTransitioning Delegate Protocol ReferenceView Controller Programming Guide for iOSUIMotionEffect Class Referencehttp://developer.apple.com/
Apple Developer Forumshttp://devforums.apple.com