//set text attributestextLayer.foregroundColor=[UIColorblackColor].CGColor;textLayer.alignmentMode=kCAAlignmentJustified;textLayer.wrapped=YES;//choose a fontUIFont*font=[UIFontsystemFontOfSize:15];//set layer fontCFStringReffontName=(__bridgeCFStringRef)font.fontName;CGFontReffontRef=CGFontCreateWithFontName(fontName);textLayer.font=fontRef;textLayer.fontSize=font.pointSize;CGFontRelease(fontRef);//texttextLayer.string=@"Text";//scaletextLayer.contentsScale=[UIScreenmainScreen].scale;
富文本:
1234567891011121314151617181920212223242526
//create attributed stringNSMutableAttributedString*string=nil;string=[[NSMutableAttributedStringalloc]initWithString:text];//convert UIFont to a CTFontCFStringReffontName=(__bridgeCFStringRef)font.fontName;CGFloatfontSize=font.pointSize;CTFontReffontRef=CTFontCreateWithName(fontName,fontSize,NULL);//set text attributesNSDictionary*attribs=@{(__bridgeid)kCTForegroundColorAttributeName:(__bridgeid)[UIColorblackColor].CGColor,(__bridgeid)kCTFontAttributeName:(__bridgeid)fontRef};[stringsetAttributes:attribsrange:NSMakeRange(0,[textlength])];attribs=@{(__bridgeid)kCTForegroundColorAttributeName:(__bridgeid)[UIColorredColor].CGColor,(__bridgeid)kCTUnderlineStyleAttributeName:@(kCTUnderlineStyleSingle),(__bridgeid)kCTFontAttributeName:(__bridgeid)fontRef};[stringsetAttributes:attribsrange:NSMakeRange(6,5)];//release the CTFont we created earlierCFRelease(fontRef);//set layer texttextLayer.string=string;
修改view的根layer。
12345678
+(Class)layerClass{//this makes our label create a CATextLayer//instead of a regular CALayer for its backing layerreturn[CATextLayerclass];}-(CATextLayer*)textLayer{return(CATextLayer*)self.layer;}
CATransformLayer
保存变换后的layer
CAGradientLayer
用于绘制渐变层。
线性渐变。
123456789101112131415161718
//create gradient layer and add it to our container viewCAGradientLayer*gradientLayer=[CAGradientLayerlayer];gradientLayer.frame=self.containerView.bounds;[self.containerView.layeraddSublayer:gradientLayer];//set gradient colorsgradientLayer.colors=@[(__bridgeid)[UIColorredColor].CGColor,(__bridgeid)[UIColorblueColor].CGColor,(__bridgeid)[UIColorgreenColor].CGColor];//set locationsgradientLayer.locations=@[@0.0,@0.25,@0.5];//set gradient start and end pointsgradientLayer.startPoint=CGPointMake(0,0);gradientLayer.endPoint=CGPointMake(1,1);
放射性渐变。
CAReplicatorLayer
用于高效绘制相似的layer。
123456789101112131415161718192021222324
//create a replicator layer and add it to our viewCAReplicatorLayer*replicator=[CAReplicatorLayerlayer];replicator.frame=self.containerView.bounds;[self.containerView.layeraddSublayer:replicator];//configure the replicatorreplicator.instanceCount=10;//apply a transform for each instanceCATransform3Dtransform=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 instancereplicator.instanceBlueOffset=-0.1;replicator.instanceGreenOffset=-0.1;//create a sublayer and place it inside the replicatorCALayer*layer=[CALayerlayer];layer.frame=CGRectMake(100.0f,100.0f,100.0f,100.0f);layer.backgroundColor=[UIColorwhiteColor].CGColor;[replicatoraddSublayer:layer];
绘制镜面
1234567891011121314151617181920212223242526
+(Class)layerClass{return[CAReplicatorLayerclass];}-(void)setUp{//configure replicatorCAReplicatorLayer*layer=(CAReplicatorLayer*)self.layer;layer.instanceCount=2;//move reflection instance below original and flip verticallyCATransform3Dtransform=CATransform3DIdentity;CGFloatverticalOffset=self.bounds.size.height+2;transform=CATransform3DTranslate(transform,0,verticalOffset,0);transform=CATransform3DScale(transform,1,-1,0);layer.instanceTransform=transform;//reduce alpha of reflection layerlayer.instanceAlphaOffset=-0.6;}-(id)initWithFrame:(CGRect)frame{//this is called when view is created in codeif((self=[superinitWithFrame:frame])){[selfsetUp];}returnself;}
+(Class)layerClass{return[CAScrollLayerclass];}-(void)setUp{//enable clippingself.layer.masksToBounds=YES;//attach pan gesture recognizerUIPanGestureRecognizer*recognizer=nil;recognizer=[[UIPanGestureRecognizeralloc]initWithTarget:selfaction:@selector(pan:)];[selfaddGestureRecognizer:recognizer];}-(id)initWithFrame:(CGRect)frame{//this is called when view is created in codeif((self=[superinitWithFrame:frame])){[selfsetUp];}returnself;}-(void)pan:(UIPanGestureRecognizer*)recognizer{//get the offset by subtracting the pan gesture//translation from the current bounds originCGPointoffset=self.bounds.origin;offset.x-=[recognizertranslationInView:self].x;offset.y-=[recognizertranslationInView:self].y;//scroll the layer[(CAScrollLayer*)self.layerscrollToPoint:offset];//reset the pan gesture translation[recognizersetTranslation:CGPointZeroinView:self];}
CATiledLayer
用于加载尺寸巨大的图片。
123456789101112131415161718192021222324252627
//add the tiled layerCATiledLayer*tileLayer=[CATiledLayerlayer];tileLayer.frame=CGRectMake(0,0,2048,2048);tileLayer.delegate=self;[self.scrollView.layeraddSublayer:tileLayer];//configure the scroll viewself.scrollView.contentSize=tileLayer.frame.size;//draw layer[tileLayersetNeedsDisplay];-(void)drawLayer:(CATiledLayer*)layerinContext:(CGContextRef)ctx{//determine tile coordinateCGRectbounds=CGContextGetClipBoundingBox(ctx);NSIntegerx=floor(bounds.origin.x/layer.tileSize.width);NSIntegery=floor(bounds.origin.y/layer.tileSize.height);//load tile imageNSString*imageName=[NSStringstringWithFormat:@"Snowman_%02i_%02i, x, y];NSString*imagePath=[[NSBundlemainBundle]pathForResource:imageNameofType:@"jpg"];UIImage*tileImage=[UIImageimageWithContentsOfFile:imagePath];//draw tileUIGraphicsPushContext(ctx);[tileImagedrawInRect:bounds];UIGraphicsPopContext();}
CAEmitterLayer
粒子特效。
12345678910111213141516171819202122
//create particle emitter layerCAEmitterLayer*emitter=[CAEmitterLayerlayer];emitter.frame=self.containerView.bounds;[self.containerView.layeraddSublayer:emitter];//configure emitteremitter.renderMode=kCAEmitterLayerAdditive;emitter.emitterPosition=CGPointMake(emitter.frame.size.width/2.0,emitter.frame.size.height/2.0);//create a particle templateCAEmitterCell*cell=[[CAEmitterCellalloc]init];cell.contents=(__bridgeid)[UIImageimageNamed:@"Spark.png"].CGImage;cell.birthRate=150;cell.lifetime=5.0;cell.color=[UIColorcolorWithRed:1green:0.5blue:0.1alpha:1.0].CGColor;cell.alphaSpeed=-0.4;cell.velocity=50;cell.velocityRange=50;cell.emissionRange=M_PI*2.0;//add particle template to emitteremitter.emitterCells=@[cell];
AVPlayerLayer
播放视频。
12345678910111213
//get video URLNSURL*URL=[[NSBundlemainBundle]URLForResource:@"Ship"withExtension:@"mp4"];//create player and player layerAVPlayer*player=[AVPlayerplayerWithURL:URL];AVPlayerLayer*playerLayer=[AVPlayerLayerplayerLayerWithPlayer:player];//set player layer frame and attach it to our viewplayerLayer.frame=self.containerView.bounds;[self.containerView.layeraddSublayer:playerLayer];//play the video[playerplay];
Implicit Animations
隐式动画。改变支持动画的属性,自动生成动画。
duration -> transaction,默认为0.25秒
type -> layer action
transaction只能begin和commit。
每次runloop会执行一次transaction。
1234567891011121314151617181920212223
//begin a new transaction[CATransactionbegin];//set the animation duration to 1 second[CATransactionsetAnimationDuration:1.0];//add the spin animation on completion[CATransactionsetCompletionBlock:^{//rotate the layer 90 degreesCGAffineTransformtransform=self.colorLayer.affineTransform;transform=CGAffineTransformRotate(transform,M_PI_2);self.colorLayer.affineTransform=transform;}];//randomize the layer background colorCGFloatred=arc4random()/(CGFloat)INT_MAX;CGFloatgreen=arc4random()/(CGFloat)INT_MAX;CGFloatblue=arc4random()/(CGFloat)INT_MAX;self.colorLayer.backgroundColor=[UIColorcolorWithRed:redgreen:greenblue:bluealpha:1.0].CGColor;//commit the transaction[CATransactioncommit];}
-(void)applyBasicAnimation:(CABasicAnimation*)animationtoLayer:(CALayer*)layer{//set the from value (using presentation layer if available) animation.fromValue=[layer.presentationLayer?:layervalueForKeyPath:animation.keyPath];//update the property in advance//note: this approach will only work if toValue != nil[CATransactionbegin];[CATransactionsetDisableActions:YES];[layersetValue:animation.toValueforKeyPath:animation.keyPath];[CATransactioncommit];//apply animation to layer[layeraddAnimation:animationforKey:nil];}
Transitions
CATransition : CAAnimation
type
subtype
视图控制器切换时使用,效果更平滑;
Cancel animations
-removeAnimationForKey:
Layer time
Tuning for speed
合理分配绘图任务至CPU和GPU。
The Stages of an Animation
Layout:setup layers
Display:draw backing image,call -drawRect:
Prepare:prepare send animation data to render server
Commit:package up and send over IPC
render server form render tree:
calculate intermediate values
render to screen
只有最后一步通过GPU处理。
开发者只能控制前两步,layout和display。