CAGradientLayer
?
CAGradientLayer?is used to generate a smooth gradient between two or more colors. 是用来产生渐变色的。
It‘s possible to replicate the appearance of a?CAGradientLayer?using Core Graphics to draw into an ordinary layer‘s backing image, but the advantage of using a?CAGradientLayer?instead is that the drawing is hardware accelerated.
好处是硬件加速的。
Basic Gradients
?
We‘ll start with a simple diagonal gradient from red to blue (see Listing 6.6). The gradient colors are specified using the?colors?property, which is an array. The?colors?array expects values of type?CGColorRef?(which is not an?NSObject?derivative), so we need to use the bridging trick that we first saw in Chapter 2 to keep the compiler happy.
gradients colors 是一个数组,要用到CGColorRef 。
?
CAGradientLayer?also has?startPoint?and?endPoint?properties that define the direction of the gradient. These are specified in?unit coordinates, not points, so the top-left corner of the layer is specified with {0, 0} and the bottom-right corner is {1, 1}. The resulting gradient is shown in Figure 6.6.
unit coordinates,不是points,top left corner of the layer 是{0,0},而右下角是{1,1}
?
Listing 6.6?A Simple Two-Color Diagonal Gradient
@interface?ViewController ()
?
@property?(nonatomic,?weak)?IBOutlet?UIView?*containerView;
@end
@implementation?ViewController
- (void)viewDidLoad {
[super?viewDidLoad];
//create gradient layer and add it to our container view
?
CAGradientLayer?*gradientLayer = [CAGradientLayer?layer];
gradientLayer.frame?=?self.containerView.bounds;
[self.containerView.layer?addSublayer:gradientLayer];
//set gradient colors
gradientLayer.colors?=?@[(__bridge id)[UIColor?redColor].CGColor, (__bridge id)[UIColor?blueColor].CGColor];
//set gradient start and end points
gradientLayer.startPoint?=?CGPointMake(0,?0); gradientLayer.endPoint?=?CGPointMake(1,?1);
}
@end
?
Multipart Gradients 多部分组成的Gradients
The?colors?array can contain as many colors as you like, so it is simple to create a multipart gradient such as a rainbow. By default, the colors in the gradient will be evenly spaced, but we can adjust the spacing using the?locations?property.
?
The?locations?property is an array of floating-point values (boxed as?NSNumber?objects). These values define the positions for each distinct color in the colors array, and are specified in unit coordinates, with 0.0 representing the start of the gradient and 1.0 representing the end.
locations 属性也是一个array .这些值定义了位置,为每个颜色,并指明在unit coordinates .
?
It is not obligatory to supply a?locations?array, but if you do, you must ensure that the number of locations matches the number of colors or you‘ll get a blank gradient.
指定locations 不是强制的,但是如果你做了,你需要确保locations 的数量和colors数量相同。否则,可能会获取一个空白的gradient
Listing 6.7 shows a modified version of the diagonal gradient code from Listing 6.6. We now have a three-part gradient from red to yellow to green. A?locations?array has been specified with the values 0.0, 0.25, and 0.5, which causes the gradient to be squashed up toward the top-left corner of the view (see Figure 6.7).
?
Listing 6.7?Using the?locations?Array to Offset a Gradient
- (void)viewDidLoad {
[super?viewDidLoad];
//create gradient layer and add it to our container view
?
CAGradientLayer?*gradientLayer = [CAGradientLayer?layer];
gradientLayer.frame?=?self.containerView.bounds;
[self.containerView.layer?addSublayer:gradientLayer];
//set gradient colors
gradientLayer.colors?=?@[(__bridge id)[UIColor?redColor].CGColor, (__bridge id)[UIColor?yellowColor].CGColor, (__bridge id)[UIColor?greenColor].CGColor];
//set locations
gradientLayer.locations?=?@[@0.0,?@0.25,?@0.5];
//set gradient start and end points
gradientLayer.startPoint?=?CGPointMake(0,?0);
?
gradientLayer.endPoint?=?CGPointMake(1,?1);
}
?
Figure 6.7?A three-color gradient, offset to the top left using the?locations?array
CAReplicatorLayer
?
The?CAReplicatorLayer?class is designed to efficiently generate collections of similar layers.
是为了产生相似layers的容器的。
It works by drawing one or more duplicate copies of each of its sublayers, applying a different transform to each duplicate. This is probably easier to demonstrate than to explain, so let‘s construct an example.
Repeating Layers
?
In Listing 6.8, we create a small white square layer in the middle of the screen, then turn it into a ring of ten layers using?CAReplicatorLayer. The?instanceCount?property specifies how many times the layer should be repeated.
instanceCount 属性指明了这个layer需要复制多少次?
The?instanceTransform?applies a?CATransform3D?(in this case, a translation and rotation that moves the layer to the next point in the circle).
The transform is applied incrementally, with each instance positioned relative to the previous one. This is why the duplicates don‘t all end up in the same place. Figure 6.8 shows the result.
?
Listing 6.8?Repeating Layers Using?CAReplicatorLayer
@interface?ViewController ()
@property?(nonatomic,weak)IBOutlet?UIView?*containerView;
@end
@implementation?ViewController
- (void)viewDidLoad {
[super?viewDidLoad];
//create a replicator layer and add it to our view
?
CAReplicatorLayer?*replicator = [CAReplicatorLayer?layer];
replicator.frame?=?self.containerView.bounds;
[self.containerView.layer?addSublayer:replicator];
//configure the replicator
replicator.instanceCount?=?10;
//apply a transform for each instance
?
CATransform3D?transform =?CATransform3DIdentity;
transform =?CATransform3DTranslate(transform,?0,?200,?0);
transform =?CATransform3DRotate(transform,?M_PI?/?5.0,?0,?0,?1);
transform =?CATransform3DTranslate(transform,?0, -200,?0);
?
replicator.instanceTransform?= transform;
//apply a color shift for each instance
?
replicator.instanceBlueOffset?= -0.1;
replicator.instanceGreenOffset?= -0.1;
//create a sublayer and place it inside the replicator
?
CALayer?*layer = [CALayer?layer];
layer.frame?=?CGRectMake(100.0f,?100.0f,?100.0f,?100.0f);
layer.backgroundColor?= [UIColor?whiteColor].CGColor;
[replicator?addSublayer:layer];
}
?
@end