第六章: Specialized Layers
? 類別
用途
CAEmitterLayer
用于實現基于Core Animation粒子發射系統。發射器層對象控制粒子的生成和起源
CAGradientLayer
用于繪制一個顏色漸變填充圖層的形狀(所有圓角矩形邊界內的部分)
CAEAGLLayer/CAOpenGLLayer
用于設置需要使用OpenGL ES(iOS)或OpenGL(OS X)繪制的內容與內容儲備。
CAReplicatorLayer
當你想自動生成一個或多個子層的拷貝。復制器為你生成拷貝并使用你指定的屬性值以修改復制品的外觀和屬性。
CAScrollLayer
用于管理由多個子區域組成的大的可滾動區域
CAShaperLayer
用于繪制三次貝塞爾曲線。CAShaperLayer對繪制基于路徑的形狀非常有幫助。因為CAShaperLayer總是生成一個最新的路徑。而如果將路徑畫在圖層儲備中,一旦圖層被縮放,形狀就變形了。
CATextLayer
用于渲染一個無格式或屬性文本字符
CATransformLayer
用于渲染一個真3D的圖層層級。而不是由其他圖層類實現的2D圖層層級。
QCCompositionLayer
用于渲染一個Quartz組件元素(僅在OS X中有效)
? CAShapeLayer 使用CGPath繪制矢量圖,UIBezierPath類可以創建基于矢量的路徑,此類是Core Graphics框架關于path的一個封裝。它可以定義簡單的形狀,如橢圓或者矩形,或者有多個直線和曲線段組成的形狀。
源碼在這里下載:http://www.informit.com/title/9780133440751
例子6.1
[objc] ?view plaincopyprint?
@interface?ViewController?()?? ?? @property?(nonatomic,?weak)?IBOutlet?UIView?*containerView;?? ?? @end?? ?? @implementation?ViewController?? ?? -?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????UIBezierPath?*path?=?[[UIBezierPath?alloc]?init];?? ????[path?moveToPoint:CGPointMake(175,?100)];?? ????[path?addArcWithCenter:CGPointMake(150,?100)?radius:25?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(150,?125)];?? ????[path?addLineToPoint:CGPointMake(150,?175)];?? ????[path?addLineToPoint:CGPointMake(125,?225)];?? ????[path?moveToPoint:CGPointMake(150,?175)];?? ????[path?addLineToPoint:CGPointMake(175,?225)];?? ????[path?moveToPoint:CGPointMake(100,?150)];?? ????[path?addLineToPoint:CGPointMake(200,?150)];?? ?????? ???? ????CAShapeLayer?*shapeLayer?=?[CAShapeLayer?layer];?? ????shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;?? ????shapeLayer.fillColor?=?[UIColor?clearColor].CGColor;?? ????shapeLayer.lineWidth?=?5;?? ????shapeLayer.lineJoin?=?kCALineJoinRound;?? ????shapeLayer.lineCap?=?kCALineCapRound;?? ????shapeLayer.path?=?path.CGPath;?? ?????? ???? ????[self.containerView.layer?addSublayer:shapeLayer];?? }?? ?? @end?? 先說說CAShapeLayer的屬性設置 1. 線顏色
[objc] ?view plaincopyprint?
@property?CGColorRef?strokeColor?? 2. 填充色
[objc] ?view plaincopyprint?
@property?CGColorRef?fillColor?? 3. 填充規則
[objc] ?view plaincopyprint?
@property(copy)?NSString?*fillRule?? 修改例子6.1 默認值kCAFillRuleNonZero的情況
[objc] ?view plaincopyprint?
-?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????UIBezierPath?*path?=?[[UIBezierPath?alloc]?init];?? ????[path?moveToPoint:CGPointMake(200,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:50?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(250,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:100?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ?? ???? ????CAShapeLayer?*shapeLayer?=?[CAShapeLayer?layer];?? ????shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;?? ????shapeLayer.fillColor?=?[UIColor?blueColor].CGColor;?? ????shapeLayer.fillRule?=?kCAFillRuleNonZero;?? ???? ?? ????shapeLayer.lineWidth?=?5;?? ????shapeLayer.lineJoin?=?kCALineJoinBevel;?? ????shapeLayer.lineCap?=?kCALineCapRound;?? ????shapeLayer.path?=?path.CGPath;?? ?????? ???? ????[self.containerView.layer?addSublayer:shapeLayer];?? }?? 再修改
[objc] ?view plaincopyprint?
-?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????UIBezierPath?*path?=?[[UIBezierPath?alloc]?init];?? ????[path?moveToPoint:CGPointMake(200,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:50?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(250,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:100?startAngle:0?endAngle:-2*M_PI?clockwise:NO];?? ?? ???? ????CAShapeLayer?*shapeLayer?=?[CAShapeLayer?layer];?? ????shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;?? ????shapeLayer.fillColor?=?[UIColor?blueColor].CGColor;?? ????shapeLayer.fillRule?=?kCAFillRuleNonZero;?? ???? ?? ????shapeLayer.lineWidth?=?5;?? ????shapeLayer.lineJoin?=?kCALineJoinBevel;?? ????shapeLayer.lineCap?=?kCALineCapRound;?? ????shapeLayer.path?=?path.CGPath;?? ?????? ???? ????[self.containerView.layer?addSublayer:shapeLayer];?? }?? kCAFillRuleEvenOdd的情況
修改代碼
[objc] ?view plaincopyprint?
-?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????UIBezierPath?*path?=?[[UIBezierPath?alloc]?init];?? ????[path?moveToPoint:CGPointMake(200,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:50?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(250,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:100?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ?? ???? ????CAShapeLayer?*shapeLayer?=?[CAShapeLayer?layer];?? ????shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;?? ????shapeLayer.fillColor?=?[UIColor?blueColor].CGColor;?? ???? ????shapeLayer.fillRule?=?kCAFillRuleEvenOdd;?? ?? ????shapeLayer.lineWidth?=?5;?? ????shapeLayer.lineJoin?=?kCALineJoinBevel;?? ????shapeLayer.lineCap?=?kCALineCapRound;?? ????shapeLayer.path?=?path.CGPath;?? ?????? ???? ????[self.containerView.layer?addSublayer:shapeLayer];?? }?? 同樣修改
[objc] ?view plaincopyprint?
-?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????UIBezierPath?*path?=?[[UIBezierPath?alloc]?init];?? ????[path?moveToPoint:CGPointMake(200,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:50?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(250,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:100?startAngle:0?endAngle:-2*M_PI?clockwise:NO];?? ?? ???? ????CAShapeLayer?*shapeLayer?=?[CAShapeLayer?layer];?? ????shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;?? ????shapeLayer.fillColor?=?[UIColor?blueColor].CGColor;?? ???? ????shapeLayer.fillRule?=?kCAFillRuleEvenOdd;?? ?? ????shapeLayer.lineWidth?=?5;?? ????shapeLayer.lineJoin?=?kCALineJoinBevel;?? ????shapeLayer.lineCap?=?kCALineCapRound;?? ????shapeLayer.path?=?path.CGPath;?? ?????? ???? ????[self.containerView.layer?addSublayer:shapeLayer];?? }?? 繼續為了看清奇偶的效果,畫3個同方向圓圈
[objc] ?view plaincopyprint?
-?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????UIBezierPath?*path?=?[[UIBezierPath?alloc]?init];?? ????[path?moveToPoint:CGPointMake(200,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:50?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(250,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:100?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(300,?150)];?? ????[path?addArcWithCenter:CGPointMake(150,?150)?radius:150?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ?? ???? ????CAShapeLayer?*shapeLayer?=?[CAShapeLayer?layer];?? ????shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;?? ????shapeLayer.fillColor?=?[UIColor?blueColor].CGColor;?? ???? ????shapeLayer.fillRule?=?kCAFillRuleEvenOdd;?? ?? ????shapeLayer.lineWidth?=?5;?? ????shapeLayer.lineJoin?=?kCALineJoinBevel;?? ????shapeLayer.lineCap?=?kCALineCapRound;?? ????shapeLayer.path?=?path.CGPath;?? ?????? ???? ????[self.containerView.layer?addSublayer:shapeLayer];?? }?? 以上我們應該清楚不同的規則了吧,挪用別人的描述 nonzero字面意思是“非零”。按該規則,要判斷一個點是否在圖形內,從該點作任意方向的一條射線,然后檢測射線與圖形路徑的交點情況。從0開始計數,路徑從左向右穿過射線則計數加1,從右向左穿過射線則計數減1。得出計數結果后,如果結果是0,則認為點在圖形外部,否則認為在內部。下圖演示了nonzero規則:
?
evenodd字面意思是“奇偶”。按該規則,要判斷一個點是否在圖形內,從該點作任意方向的一條射線,然后檢測射線與圖形路徑的交點的數量。如果結果是奇數則認為點在內部,是偶數則認為點在外部。下圖演示了evenodd?規則: 4. 線端點類型
[objc] ?view plaincopyprint?
@property(copy)?NSString?*lineCap?? 5. 線連接類型
[objc] ?view plaincopyprint?
@property(copy)?NSString?*lineJoin?? 6. 線寬
[objc] ?view plaincopyprint?
@property?CGFloat?lineWidth?? 7. 線型模板
[objc] ?view plaincopyprint?
@property(copy)?NSArray?*lineDashPattern?? 這是一個NSNumber的數組,索引從1開始記,奇數位數值表示實線長度,偶數位數值表示空白長度
8. 線型模板的起始位置
[objc] ?view plaincopyprint?
@property?CGFloat?lineDashPhase?? 修改例子6.1,為了看得更清楚,把lineCap的設置注釋,,自己看看不注釋是什么結果
[objc] ?view plaincopyprint?
-?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?? ???? ????UIBezierPath?*path?=?[[UIBezierPath?alloc]?init];?? ????[path?moveToPoint:CGPointMake(175,?100)];?? ????[path?addArcWithCenter:CGPointMake(150,?100)?radius:25?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(150,?125)];?? ????[path?addLineToPoint:CGPointMake(150,?175)];?? ????[path?addLineToPoint:CGPointMake(125,?225)];?? ????[path?moveToPoint:CGPointMake(150,?175)];?? ????[path?addLineToPoint:CGPointMake(175,?225)];?? ????[path?moveToPoint:CGPointMake(100,?150)];?? ????[path?addLineToPoint:CGPointMake(200,?150)];?? ?? ???? ????CAShapeLayer?*shapeLayer?=?[CAShapeLayer?layer];?? ????shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;?? ????shapeLayer.fillColor?=?[UIColor?clearColor].CGColor;?? ?? ????shapeLayer.lineWidth?=?5;?? ????shapeLayer.lineDashPattern?=?[NSArray?arrayWithObjects:[NSNumber?numberWithInt:20],?[NSNumber?numberWithInt:10],?[NSNumber?numberWithInt:10],?[NSNumber?numberWithInt:2],?nil?nil];?? ???? ????shapeLayer.lineJoin?=?kCALineJoinBevel;?? ???? ????shapeLayer.path?=?path.CGPath;?? ?? ???? ????[self.containerView.layer?addSublayer:shapeLayer];?? }?? 再修改lineDashPhase值=15
9. 最大斜接長度。
?
[objc] ?view plaincopyprint?
@property?CGFloat?miterLimit?? ?
斜接長度指的是在兩條線交匯處內角和外角之間的距離。
只有lineJoin屬性為kCALineJoinMiter時miterLimit才有效
邊角的角度越小,斜接長度就會越大。
為了避免斜接長度過長,我們可以使用?miterLimit?屬性。
如果斜接長度超過?miterLimit?的值,邊角會以?lineJoin的?"bevel"即kCALineJoinBevel類型來顯示
10. 部分繪線
[objc] ?view plaincopyprint?
@property?CGFloat?strokeStart?? @property?CGFloat?strokeEnd?? 都是0.0~1.0的取值范圍 具體看修改例子6.1
[objc] ?view plaincopyprint?
-?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?? ???? ????UIBezierPath?*path?=?[[UIBezierPath?alloc]?init];?? ????[path?moveToPoint:CGPointMake(175,?100)];?? ????[path?addArcWithCenter:CGPointMake(150,?100)?radius:25?startAngle:0?endAngle:2*M_PI?clockwise:YES];?? ????[path?moveToPoint:CGPointMake(150,?125)];?? ????[path?addLineToPoint:CGPointMake(150,?175)];?? ????[path?addLineToPoint:CGPointMake(125,?225)];?? ????[path?moveToPoint:CGPointMake(150,?175)];?? ????[path?addLineToPoint:CGPointMake(175,?225)];?? ????[path?moveToPoint:CGPointMake(100,?150)];?? ????[path?addLineToPoint:CGPointMake(200,?150)];?? ?? ???? ????CAShapeLayer?*shapeLayer?=?[CAShapeLayer?layer];?? ????shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;?? ????shapeLayer.fillColor?=?[UIColor?clearColor].CGColor;?? ?? ????shapeLayer.lineWidth?=?5;?? ???? ???? ????shapeLayer.lineJoin?=?kCALineJoinBevel;?? ????shapeLayer.lineCap?=?kCALineCapRound;?? ????shapeLayer.strokeStart?=?0.1;?? ????shapeLayer.strokeEnd?=?0.6;?? ????shapeLayer.path?=?path.CGPath;?? ?? ???? ????[self.containerView.layer?addSublayer:shapeLayer];?? }?? UIBezierPath貝塞爾曲線的常用繪圖方法 1. 矩形
[objc] ?view plaincopyprint?
+?(UIBezierPath?*)bezierPathWithRect:(CGRect)rect?? 2.?矩形內切橢圓
[objc] ?view plaincopyprint?
+?(UIBezierPath?*)bezierPathWithOvalInRect:(CGRect)rect?? 3. 圓角矩形
[objc] ?view plaincopyprint?
+?(UIBezierPath?*)bezierPathWithRoundedRect:(CGRect)rect?cornerRadius:(CGFloat)cornerRadius?? 4. 可設置的圓角矩形
[objc] ?view plaincopyprint?
+?(UIBezierPath?*)bezierPathWithRoundedRect:(CGRect)rect?byRoundingCorners:(UIRectCorner)corners?cornerRadii:(CGSize)cornerRadii?? ?
corners有以下幾種類型:
? ?UIRectCornerTopLeft,
?? UIRectCornerTopRight,
?? UIRectCornerBottomLeft,
?? UIRectCornerBottomRight,
?? UIRectCornerAllCorners
?
cornerRadii表示的是四個圓角拼成的橢圓的長、短半徑尺寸。
5. 圓弧
[objc] ?view plaincopyprint?
+?(UIBezierPath?*)bezierPathWithArcCenter:(CGPoint)center?radius:(CGFloat)radius?startAngle:(CGFloat)startAngle?endAngle:(CGFloat)endAngle?clockwise:(BOOL)clockwise?? -?(void)addArcWithCenter:(CGPoint)center?radius:(CGFloat)radius?startAngle:(CGFloat)startAngle?endAngle:(CGFloat)endAngle?clockwise:(BOOL)clockwise?? 以下需要配合moveToPoint使用
[objc] ?view plaincopyprint?
-?(void)moveToPoint:(CGPoint)point?? 6. 直線
[objc] ?view plaincopyprint?
-?(void)addLineToPoint:(CGPoint)point?? 7. 曲線
[objc] ?view plaincopyprint?
-?(void)addCurveToPoint:(CGPoint)endPoint?controlPoint1:(CGPoint)controlPoint1?controlPoint2:(CGPoint)controlPoint2?? 8.?二元曲線
[objc] ?view plaincopyprint?
-?(void)addQuadCurveToPoint:(CGPoint)endPoint?controlPoint:(CGPoint)controlPoint?? UIBezierPath的屬性設置(這些屬性在使用CAShapeLayer時,只遵循CAShapeLayer的設置) 1. 線寬
[objc] ?view plaincopyprint?
@property(nonatomic)?CGFloat?lineWidth?? ?
2. 端點類型
[objc] ?view plaincopyprint?
@property(nonatomic)?CGLineCap?lineCapStyle?? 3. 連接類型
[objc] ?view plaincopyprint?
@property(nonatomic)?CGLineJoin?lineJoinStyle?? 4. 設置線型
[objc] ?view plaincopyprint?
-?(void)setLineDash:(const?CGFloat?*)pattern?count:(NSInteger)count?phase:(CGFloat)phase?? pattern:C類型的線型數據。如:CGFloat dashStyle[] = { 1.0f, 2.0f };
count:pattern中的數據個數 phase: 開始畫線型的起始位置
其他的我在這里就不多說了
CATextLayer ? 例子6.2
[objc] ?view plaincopyprint?
@interface?ViewController?()?? ?? @property?(nonatomic,?weak)?IBOutlet?UIView?*labelView;?? ?? @end?? ?? @implementation?ViewController?? ?? -?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????CATextLayer?*textLayer?=?[CATextLayer?layer];?? ????textLayer.frame?=?self.labelView.bounds;?? ????[self.labelView.layer?addSublayer:textLayer];?? ?? ???? ???? ?????? ???? ????textLayer.foregroundColor?=?[UIColor?blackColor].CGColor;?? ????textLayer.alignmentMode?=?kCAAlignmentJustified;?? ???? ????textLayer.wrapped?=?YES;?? ?????? ???? ????UIFont?*font?=?[UIFont?systemFontOfSize:15];?? ?????? ???? ????CFStringRef?fontName?=?(__bridge?CFStringRef)font.fontName;?? ????CGFontRef?fontRef?=?CGFontCreateWithFontName(fontName);?? ????textLayer.font?=?fontRef;?? ????textLayer.fontSize?=?font.pointSize;?? ????CGFontRelease(fontRef);?? ?????? ???? ????NSString?*text?=?@"Lorem?ipsum?dolor?sit?amet,?consectetur?adipiscing?\? ????elit.?Quisque?massa?arcu,?eleifend?vel?varius?in,?facilisis?pulvinar?\? ????leo.?Nunc?quis?nunc?at?mauris?pharetra?condimentum?ut?ac?neque.?Nunc?\? ????elementum,?libero?ut?porttitor?dictum,?diam?odio?congue?lacus,?vel?\? ????fringilla?sapien?diam?at?purus.?Etiam?suscipit?pretium?nunc?sit?amet?\? ????lobortis";?? ?????? ???? ????textLayer.string?=?text;?? }?? ?? @end?? 仔細看文字周圍很模糊,解決這個問題需要設置contentsScale 修改“textLayer.contentsScale = [UIScreen mainScreen].scale;”
Rich Text 例子6.3 代碼不貼了
CATextLayer?also renders much faster than UILabel. It’s a little-known fact that on?iOS6 and earlier,UILabel actually uses WebKit?to?do?its text drawing, which carries a significant performance overhead when you are drawing a lot of text.CATextLayer uses Core Text?and is significantlyfaster.
例子6.4使用layer實現的label,有興趣的完善一下
CATransformLayer 例子6.5 代碼不貼了 修改一下,可以實現簡單的拖動旋轉(只是試驗代碼)
[objc] ?view plaincopyprint?
@interface?ViewController?()?? {?? ????CGPoint?startPoint;?? ?? ????CATransformLayer?*s_Cube;?? ?? ????float?pix,?piy;?? }?? ?? @property?(nonatomic,?weak)?IBOutlet?UIView?*containerView;?? ?? @end?? ?? @implementation?ViewController?? ?? -?(CALayer?*)faceWithTransform:(CATransform3D)transform?? {?? ???? ????CALayer?*face?=?[CALayer?layer];?? ????face.frame?=?CGRectMake(-50,?-50,?100,?100);?? ?????? ???? ????CGFloat?red?=?(rand()?/?(double)INT_MAX);?? ????CGFloat?green?=?(rand()?/?(double)INT_MAX);?? ????CGFloat?blue?=?(rand()?/?(double)INT_MAX);?? ????face.backgroundColor?=?[UIColor?colorWithRed:red?? ???????????????????????????????????????????green:green?? ????????????????????????????????????????????blue:blue?? ???????????????????????????????????????????alpha:1.0].CGColor;?? ?? ???? ????face.transform?=?transform;?? ????return?face;?? }?? ?? -?(CALayer?*)cubeWithTransform:(CATransform3D)transform?? {?? ???? ????CATransformLayer?*cube?=?[CATransformLayer?layer];?? ?????? ???? ????CATransform3D?ct?=?CATransform3DMakeTranslation(0,?0,?50);?? ????[cube?addSublayer:[self?faceWithTransform:ct]];?? ?????? ???? ????ct?=?CATransform3DMakeTranslation(50,?0,?0);?? ????ct?=?CATransform3DRotate(ct,?M_PI_2,?0,?1,?0);?? ????[cube?addSublayer:[self?faceWithTransform:ct]];?? ?????? ???? ????ct?=?CATransform3DMakeTranslation(0,?-50,?0);?? ????ct?=?CATransform3DRotate(ct,?M_PI_2,?1,?0,?0);?? ????[cube?addSublayer:[self?faceWithTransform:ct]];?? ?????? ???? ????ct?=?CATransform3DMakeTranslation(0,?50,?0);?? ????ct?=?CATransform3DRotate(ct,?-M_PI_2,?1,?0,?0);?? ????[cube?addSublayer:[self?faceWithTransform:ct]];?? ?????? ???? ????ct?=?CATransform3DMakeTranslation(-50,?0,?0);?? ????ct?=?CATransform3DRotate(ct,?-M_PI_2,?0,?1,?0);?? ????[cube?addSublayer:[self?faceWithTransform:ct]];?? ?????? ???? ????ct?=?CATransform3DMakeTranslation(0,?0,?-50);?? ????ct?=?CATransform3DRotate(ct,?M_PI,?0,?1,?0);?? ????[cube?addSublayer:[self?faceWithTransform:ct]];?? ?????? ???? ????CGSize?containerSize?=?self.containerView.bounds.size;?? ????cube.position?=?CGPointMake(containerSize.width?/?2.0,?? ????????????????????????????????containerSize.height?/?2.0);?? ?????? ???? ????cube.transform?=?transform;?? ????return?cube;?? }?? ?? -?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????CATransform3D?pt?=?CATransform3DIdentity;?? ????pt.m34?=?-1.0?/?500.0;?? ????self.containerView.layer.sublayerTransform?=?pt;?? ?????? ???? ????CATransform3D?c1t?=?CATransform3DIdentity;?? ????c1t?=?CATransform3DTranslate(c1t,?-100,?0,?0);?? ????CALayer?*cube1?=?[self?cubeWithTransform:c1t];?? ????s_Cube?=?(CATransformLayer?*)cube1;?? ????[self.containerView.layer?addSublayer:cube1];?? ?????? ???? ????CATransform3D?c2t?=?CATransform3DIdentity;?? ????c2t?=?CATransform3DTranslate(c2t,?100,?0,?0);?? ????c2t?=?CATransform3DRotate(c2t,?-M_PI_4,?1,?0,?0);?? ????c2t?=?CATransform3DRotate(c2t,?-M_PI_4,?0,?1,?0);?? ????CALayer?*cube2?=?[self?cubeWithTransform:c2t];?? ????[self.containerView.layer?addSublayer:cube2];?? }?? ?? -?(void)touchesBegan:(NSSet?*)touches?withEvent:(UIEvent?*)event?? {?? ????UITouch?*touch?=?[touches?anyObject];?? ?? ????startPoint?=?[touch?locationInView:self.view];?? }?? ?? -?(void)touchesMoved:(NSSet?*)touches?withEvent:(UIEvent?*)event?? {?? ????UITouch?*touch?=?[touches?anyObject];?? ?? ????CGPoint?currentPosition?=?[touch?locationInView:self.view];?? ?? ????CGFloat?deltaX?=?startPoint.x?-?currentPosition.x;?? ?? ????CGFloat?deltaY?=?startPoint.y?-?currentPosition.y;?? ?? ????CATransform3D?c1t?=?CATransform3DIdentity;?? ????c1t?=?CATransform3DTranslate(c1t,?-100,?0,?0);?? ????c1t?=?CATransform3DRotate(c1t,?pix+M_PI_2*deltaY/100,?1,?0,?0);?? ????c1t?=?CATransform3DRotate(c1t,?piy-M_PI_2*deltaX/100,?0,?1,?0);?? ?? ????s_Cube.transform?=?c1t;?? }?? ?? -?(void)touchesEnded:(NSSet?*)touches?withEvent:(UIEvent?*)event?? {?? ????UITouch?*touch?=?[touches?anyObject];?? ?? ????CGPoint?currentPosition?=?[touch?locationInView:self.view];?? ?? ????CGFloat?deltaX?=?startPoint.x?-?currentPosition.x;?? ?? ????CGFloat?deltaY?=?startPoint.y?-?currentPosition.y;?? ?? ????pix?=?M_PI_2*deltaY/100;?? ????piy?=?-M_PI_2*deltaX/100;?? }?? ?? @end?? ? ? CAGradientLayer ? 產生平滑過渡色,
? 例子6.6
[objc] ?view plaincopyprint?
interface?ViewController?()?? ?? @property?(nonatomic,?weak)?IBOutlet?UIView?*containerView;?? ?? @end?? ?? @implementation?ViewController?? ?? -?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????CAGradientLayer?*gradientLayer?=?[CAGradientLayer?layer];?? ????gradientLayer.frame?=?self.containerView.bounds;?? ????[self.containerView.layer?addSublayer:gradientLayer];?? ?????? ???? ????gradientLayer.colors?=?@[(__bridge?id)[UIColor?redColor].CGColor,?? ?????????????????????????????(__bridge?id)[UIColor?blueColor].CGColor];?? ?????? ???? ????gradientLayer.startPoint?=?CGPointMake(0,?0);?? ????gradientLayer.endPoint?=?CGPointMake(1,?1);?????? }?? ?? @end?? CAGradientLayer的屬性設置
1. 類型
[objc] ?view plaincopyprint?
@property(copy)?NSString?*type?? 目前只有NSString * const kCAGradientLayerAxial
即線性梯度變化
2. 顏色
[objc] ?view plaincopyprint?
@property(copy)?NSArray?*colors?? 3. 位置參數
[objc] ?view plaincopyprint?
@property(copy)?NSArray?*locations?? 顏色的區間分布,locations的數組長度和colors一致,?取值范圍(0, 1),而且必須是單調遞增的
修改例子6.6,增加
[objc] ?view plaincopyprint?
<p?class="p1">????gradientLayer.<span?class="s1">locations</span>?=?<span?class="s2">@[</span>[<span?class="s1">NSNumber</span>?<span?class="s3">numberWithFloat</span>:<span?class="s2">0.0</span>],?[<span?class="s1">NSNumber</span>?<span?class="s3">numberWithFloat</span>:<span?class="s2">0.2</span>]<span?class="s2">]</span>;</p>?? [objc] ?view plaincopyprint?
gradientLayer.locations?=?@[[NSNumber?numberWithFloat:0.5],?[NSNumber?numberWithFloat:0.7]];?? 4.?startPoint和endPoint
[objc] ?view plaincopyprint?
@property?CGPoint?startPoint,?endPoint;?? 取值都是相對于layer的bounds的。startPoint默認值為(0.5, 0),endPoint默認值為(0.5, 1) 修改例子6.6
gradientLayer.startPoint?分別設為?CGPointMake(0,?0);?
CGPointMake(0.25,?0);? CGPointMake(0.5,?0);? CGPointMake(0.75,?0);? CGPointMake(1,?0);? 綜合修改例子6.6
[objc] ?view plaincopyprint?
-?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????CAGradientLayer?*gradientLayer?=?[CAGradientLayer?layer];?? ????gradientLayer.frame?=?self.containerView.bounds;?? ????[self.containerView.layer?addSublayer:gradientLayer];?? ?????? ???? ????gradientLayer.colors?=?@[(__bridge?id)[UIColor?redColor].CGColor,?? ?????????????????????????????(__bridge?id)[UIColor?blueColor].CGColor];?? ?????? ????gradientLayer.locations?=?@[[NSNumber?numberWithFloat:0.5],?[NSNumber?numberWithFloat:0.7]];?? ?? ???? ????gradientLayer.startPoint?=?CGPointMake(0.75,?0.0);?? ????gradientLayer.endPoint?=?CGPointMake(1.0,?1.0);?? }?? 從以上可以看出startPoint和endPoint詩表示的漸變方向,locations是漸變區域。 也可以看出locations的取值是相對于startPoint和endPoint線段的。 在網上找的描述讓我很是不能理解
CAReplicatorLayer 例子6.8,修改一下看得更清楚些
[objc] ?view plaincopyprint?
@interface?ViewController?()?? ?? @property?(nonatomic,?weak)?IBOutlet?UIView?*containerView;?? ?? @end?? ?? @implementation?ViewController?? ?? -?(void)viewDidLoad?? {?? ????[super?viewDidLoad];?? ?????? ???? ????CAReplicatorLayer?*replicator?=?[CAReplicatorLayer?layer];?? ????replicator.frame?=?self.containerView.bounds;?? ????[self.containerView.layer?addSublayer:replicator];?? ?????? ???? ????replicator.instanceCount?=?20;?? ?????? ???? ????CATransform3D?transform?=?CATransform3DIdentity;?? ????transform?=?CATransform3DTranslate(transform,?0,?-10,?0);?? ????transform?=?CATransform3DRotate(transform,?M_PI?/?10.0,?0,?0,?1);?? ????transform?=?CATransform3DTranslate(transform,?0,?10,?0);?? ????replicator.instanceTransform?=?transform;?? ?????? ???? ????replicator.instanceBlueOffset?=?-0.1;?? ????replicator.instanceGreenOffset?=?-0.1;?? ?????? ???? ????CALayer?*layer?=?[CALayer?layer];?? ????layer.frame?=?CGRectMake(137.5f,?25.0f,?25.0f,?25.0f);?? ????layer.backgroundColor?=?[UIColor?whiteColor].CGColor;?? ????[replicator?addSublayer:layer];?? }?? ?? @end?? CAReplicatorLayer應用最多的可能是倒影了,下面的鏈接是個很好的圖片倒影例子
https://github.com/nicklockwood/ReflectionView 后面的幾個特殊layer我就不在這里列舉了,自己去研究吧 下一次,就將進入真正的動畫部分了
轉載于:https://www.cnblogs.com/geek6/p/3931097.html
總結
以上是生活随笔 為你收集整理的IOS Core Animation Advanced Techniques的学习笔记(五) 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。