The iOS 5 Developer's Cookbook Adding Reflections The iOS 5 Developer's Cookbook Adding Reflections InformIT.pdf

(210 KB) Pobierz
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
6/17/12
The iOS 5 Developer's Cookbook: Adding Reflections | The iOS 5 Developer's Cookbook: Adding …
Hello sfcarroll
View Your Cart
Account | Log Out
The Trusted Technology Learning Source
Topics
Store Authors Safari Books Online
Imprints
Explore
Home > Articles > Programming
STORE
ARTICLES
BLOGS
PODCASTS
Related Resources
The iOS 5 Developer's Cookbook: Adding
Reflections
PhoneGap Essentials: Building
Cross‑Platform Mobile Apps
By John M. Wargo
$31.99
By Erica Sadun
Oct 12, 2011
Print
Share This
Discuss
Page 1 of 1
Android Apps with App Inventor: The
Fast and Easy Way to Build Android
Apps
By Jörg H. Kloss
$35.99
Erica Sadun, author of The iOS 5
Developer's Cookbook shows how
to use reflections in your iOS
applications.
From the author of
iOS 5 Developer's Cookbook, The: Core
Concepts and Essential Recipes for iOS
Programmers, 3rd Edition
Reflections enhance the reality of
onscreen objects. They provide a
little extra visual spice beyond the
views‑floating‑over‑a‑backsplash,
which prevails as the norm.
Reflections have become especially
easy to implement thanks to the CAReplicatorLayer class. This class clones a view's layer
in real‑time and allows you to apply transforms to that replication.
Practical Asterisk 1.4 and 1.6: From
Beginner to Expert
By Stefan Wintermeyer, Stephen Bosch
$39.99
See All Related Store Items
To use reflections in your iOS applications, create a new view class and override the
layerClass class method, reporting back that the class to be used for this view is
CAReplicatorLayer . This ensures that the view's layer defaults to a replicator.
In the following example, that replicator is given the instanceCount of 2 in the
setupReflection method. It duplicates its original view to just a second instance.
Its instanceTransform specifies how the second instance is manipulated and placed on
screen: namely flipped, squeezed, and then move vertically below the original view. This
creates a small reflection at the foot of the original view.
Due to the replicator, that reflection is completely "live." Any changes to the main view
immediately update in the reflection layer. You can best use a view like this by adding
subviews, and letting the reflecting view handle all the mirroring for those items. For
example, you can add scrolling text views, web views, switches, and so forth. Any changes
to the original view are replicated, creating a completely passive reflection system.
Good reflections use a natural attrition as the "reflection" moves further away from the
original view. This example code adds an optional gradient overlay (controlled with the
class's usesGradientOverlay property, implemented via a CAGradientLayer ) that creates a
visual drop‑off from the bottom of the view.
@interface ReflectingView : UIView
{
CAGradientLayer *gradient;
}
- (void) setupReflection;
@property (nonatomic, assign) BOOL usesGradientOverlay; @end
@implementation ReflectingView
@synthesize usesGradientOverlay;
// Always use a replicator as the base layer
+ (Class) layerClass
{
return [CAReplicatorLayer class];
}
// Clean up any existing gradient from parent
- (void) dealloc
{
[gradient removeFromSuperlayer];
}
// Establish a gradient to shade the reflection
- (void) setupGradient
{
// Add a new gradient layer to the parent
www.informit.com/articles/article.aspx?p=1760503
1/3
870493325.048.png 870493325.058.png 870493325.069.png 870493325.080.png 870493325.001.png 870493325.002.png 870493325.003.png 870493325.004.png 870493325.005.png 870493325.006.png 870493325.007.png 870493325.008.png
 
870493325.009.png
 
870493325.010.png 870493325.011.png 870493325.012.png 870493325.013.png 870493325.014.png 870493325.015.png 870493325.016.png 870493325.017.png 870493325.018.png 870493325.019.png 870493325.020.png 870493325.021.png 870493325.022.png 870493325.023.png 870493325.024.png 870493325.025.png 870493325.026.png
 
870493325.027.png 870493325.028.png 870493325.029.png 870493325.030.png 870493325.031.png 870493325.032.png 870493325.033.png 870493325.034.png 870493325.035.png 870493325.036.png 870493325.037.png 870493325.038.png 870493325.039.png 870493325.040.png 870493325.041.png 870493325.042.png 870493325.043.png 870493325.044.png 870493325.045.png 870493325.046.png 870493325.047.png 870493325.049.png 870493325.050.png 870493325.051.png 870493325.052.png 870493325.053.png 870493325.054.png 870493325.055.png 870493325.056.png 870493325.057.png
 
6/17/12
The iOS 5 Developer's Cookbook: Adding Reflections | The iOS 5 Developer's Cookbook: Adding …
UIView *parent = self.superview;
if (!gradient)
{
gradient = [CAGradientLayer layer];
CGColorRef c1 = [[UIColor blackColor]
colorWithAlphaComponent:0.5f].CGColor;
CGColorRef c2 = [[UIColor blackColor]
colorWithAlphaComponent:0.9f].CGColor;
[gradient setColors:[NSArray arrayWithObjects:
(__bridge id)c1, (__bridge id)c2, nil]];
[parent.layer addSublayer:gradient];
}
// Place the gradient just below the view using the
// reflection's geometry
float desiredGap = 10.0f; // gap between view and its reflection
CGFloat shrinkFactor = 0.25f; // reflection size
CGFloat height = self.bounds.size.height;
CGFloat width = self.bounds.size.width;
CGFloat y = self.frame.origin.y;
[gradient setAnchorPoint:CGPointMake(0.0f,0.0f)];
[gradient setFrame:CGRectMake(0.0f, y + height + desiredGap,
width, height * shrinkFactor)];
[gradient removeAllAnimations];
[gradient setAnchorPoint:CGPointMake(0.0f,0.0f)];
[gradient setFrame:CGRectMake(0.0f, y + height + desiredGap,
maxDimension, height * shrinkFactor)];
[gradient removeAllAnimations];
}
// Setup the geometry for the reflected item
- (void) setupReflection
{
CGFloat height = self.bounds.size.height;
CGFloat shrinkFactor = 0.25f;
CATransform3D t = CATransform3DMakeScale(1.0, -shrinkFactor, 1.0);
// scaling centers the shadow in the view. translate in shrunken terms
float offsetFromBottom = height * ((1.0f - shrinkFactor) / 2.0f);
float inverse = 1.0 / shrinkFactor;
float desiredGap = 10.0f;
t = CATransform3DTranslate(t, 0.0, -offsetFromBottom * inverse
- height - inverse * desiredGap, 0.0f);
CAReplicatorLayer *replicatorLayer = (CAReplicatorLayer*)self.layer;
replicatorLayer.instanceTransform = t;
replicatorLayer.instanceCount = 2;
// Gradient use must be explicitely set
if (usesGradientOverlay)
[self setupGradient];
else
{
// Darken the reflection when not using a gradient
replicatorLayer.instanceRedOffset = -0.75;
replicatorLayer.instanceGreenOffset = -0.75;
replicatorLayer.instanceBlueOffset = -0.75;
}
}
@end
Share This
Save To Your Account
Page 1 of 1
From the author of
iOS 5 Developer's Cookbook, The: Core Concepts and Essential Recipes for iOS
Programmers, 3rd Edition
Discussions
Like
Showing 1 comment
Sort by oldest first
Carl Grainger
On reflection, a great snippet..
8 months ago
Like Reply
www.informit.com/articles/article.aspx?p=1760503
2/3
870493325.059.png 870493325.060.png 870493325.061.png 870493325.062.png 870493325.063.png 870493325.064.png 870493325.065.png 870493325.066.png 870493325.067.png 870493325.068.png 870493325.070.png 870493325.071.png 870493325.072.png 870493325.073.png 870493325.074.png 870493325.075.png 870493325.076.png 870493325.077.png
6/17/12
The iOS 5 Developer's Cookbook: Adding Reflections | The iOS 5 Developer's Cookbook: Adding …
M Subscribe by email S RSS
Add New Comment
Login
comments powered by DISQUS
About | Affiliates | Contact Us | Jobs | Legal Notice | Privacy Policy | Press | Promotions | Site Map | Write for Us
© 2012 Pearson Education, Informit. All rights reserved.
800 East 96th Street, Indianapolis, Indiana 46240
www.informit.com/articles/article.aspx?p=1760503
3/3
870493325.078.png 870493325.079.png 870493325.081.png 870493325.082.png
 
870493325.083.png 870493325.084.png
Zgłoś jeśli naruszono regulamin