Transform field value key paths!
position.x
position.y
1. CALayer1.1.什么是CALayer
是圖層。
1.2.CALayer有什么用用來做界面的顯示。
1.3.CALayer原理
當UIView需要顯示到屏幕上時,會調(diào)用drawRect:方法進行繪圖。并且會將所有內(nèi)容
繪制在自己的圖層上,繪圖完畢后,系統(tǒng)會將圖層拷貝到屏幕上,于是就完成了UIView的
顯示。
1.4.CALayer的基本使用
陰影shadow
圓角corner
邊框border
透明度opacity
背景色backgroundColor內(nèi)容contents
位置大小frame裁剪maskToBounds
1.5.注意
設置圓角半徑不會影響內(nèi)容,除非剪切。
可以通過拖一個UIImageView組件來檢測
1.6.CALayer所屬框架,并且介紹類型介紹
數(shù)據(jù)類型是QuartzCore框架中的。
為了跨平臺,跨了哪些平臺?
Mac系統(tǒng) iOS系統(tǒng)
1.7.UIView和CALayer的選擇如果顯示的東西需要與用戶交互,就使用UIView,如果不需要交互就使用CALayer。
CALayer的性能會高一些,因為它少了事件處理功能,更加輕量級。
2.CALayer的bounds,position,anchorPoint屬性介紹
bounds設置大小
position顯示在父控件中的位置
anchorPoint本身的哪個點與父控件的點重疊。
3. CALayer的隱式動畫
非根層的CALayer對象才存在隱式動畫。根層CALayer不存在隱式動畫
3.1.什么是根層CALayer
也就是UIView的layer屬性,這個才是根層的CALayer。自動手動創(chuàng)建添加到CALayer
上的才不是根層layer
4. CALayer的transform屬性根層:沒有動畫,需要自己做一個動畫。
需要用KVC做對比。
KVC設置旋轉(zhuǎn)屬性在時鐘案例中,旋轉(zhuǎn)到30秒的時候會出現(xiàn)問題。
有make和 沒有make的區(qū)別?
有make:不會疊加效果
沒有make:會疊加效果
CATransform3DMakeRotation(angle, x, y, z);
CATransform3DMakeScale(sx, sy, sz);
CATransform3DMakeTranslation(tx, ty, tz);
CATransform3DRotate(transform3D, angle, x, y, z);
CATransform3DScale(transform3D, sx, sy, sz);
CATransform3DTranslate(transform3D, tx, ty, tz);
5. iOS中的時間處理相關類
5.1.NSDate
5.1.1.介紹NSDate是系統(tǒng)時間類
5.1.2.獲得系統(tǒng)當前時間
5.2.NSDateFormatter5.2.1.介紹
系統(tǒng)時間格式化類
NSDate*date = [NSDatedate];
5.2.2. NSDate轉(zhuǎn)NSString
NSDate*date = [NSDatedate];
NSDateFormatter*formatter = [[NSDateFormatteralloc]init];
formatter.dateFormat=@"yyyy-MM-dd HH:mm:ss";
NSString*str = [formatterstringFromDate:date];NSLog(@"%@",str);
5.2.3. NSString轉(zhuǎn)NSDate
NSString*time =@"2015-11-29 10:18:07";
NSDateFormatter*formatter = [[NSDateFormatteralloc]init];
formatter.dateFormat=@"yyyy-MM-dd HH:mm:ss";
//設置時區(qū)
NSTimeZone*GTMzone = [NSTimeZonetimeZoneForSecondsFromGMT:0];
[formattersetTimeZone:GTMzone];NSDate*date = [formatterdateFromString:time];NSLog(@"%@",date);
5.3.NSCalendar5.3.1.介紹
是系統(tǒng)時間工具類,用于獲取時間的各個信息。并且可以做時間比較
5.3.2.獲得時間中的時,分,秒等
NSCalendar*calendar = [NSCalendarcurrentCalendar];NSDateComponents*cmp = [calendar
components:NSCalendarUnitSecond fromDate:[NSDatedate]];CGFloatsecond = cmp.second;NSLog(@"%f",second);
6. CALayer時鐘案例6.1.背景圖片設置
#pragma mark --添加表盤
-(void)addWatch{CALayer*watchLayer = [[CALayeralloc]init];
[self.view.layeraddSublayer:watchLayer];
watchLayer.bounds=CGRectMake(0,0,200,200);
watchLayer.position=
CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2);
watchLayer.anchorPoint=CGPointMake(0.5,0.5);
UIImage*image = [UIImageimageNamed:@"鐘表"];
watchLayer.contents= (__bridge id
_Nullable)(image.CGImage);
}
6.2.添加秒針
#pragma mark --添加秒針
-(void)addSecond{CALayer*secondLayer = [[CALayeralloc]init];
[self.view.layeraddSublayer:secondLayer];
secondLayer.bounds=CGRectMake(0,0,1,85);
secondLayer.position=
CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2);
secondLayer.anchorPoint=CGPointMake(0.5,1);
secondLayer.backgroundColor= [UIColorblackColor].CGColor;
self.secondLayer= secondLayer;
}
6.3.添加定時器每秒調(diào)用一次
//通過定時器的方式來使 時分秒針旋轉(zhuǎn)起來
-(void)startRun{
[NSTimerscheduledTimerWithTimeInterval:1target:self
selector:@selector(updateTime)userInfo:nilrepeats:YES];
}
6.4.獲得當前時間的秒數(shù)
//獲得一個系統(tǒng)處理時間對象
NSCalendar *calender = [NSCalendar currentCalendar];
//獲得 時間對象 來獲得當前的 時分秒
NSDateComponents *cmp =[calender
components:NSCalendarUnitSecond fromDate:[NSDate date]];
//秒
CGFloat second = cmp.second;
6.5.旋轉(zhuǎn)秒針
//計算秒針角度
CGFloatangle = (second *6*M_PI) /180;//旋轉(zhuǎn)秒針
self.secondLayer.transform=CATransform3DMakeRotation(angle,0,0,1);
6.6.添加分針
#pragma mark --添加分針
-(void)addMinute{CALayer*minuteLayer = [[CALayeralloc]init];
[self.view.layeraddSublayer:minuteLayer];
minuteLayer.bounds=CGRectMake(0,0,3,70);
minuteLayer.position=
CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2);
minuteLayer.anchorPoint=CGPointMake(0.5,1);
minuteLayer.backgroundColor= [UIColorblackColor].CGColor;
self.minuteLayer= minuteLayer;
}
6.7.獲得當前時間的分鐘數(shù)
//獲得一個系統(tǒng)處理時間對象
NSCalendar*calender = [NSCalendarcurrentCalendar];
//獲得 時間對象 來獲得當前的 時分秒
NSDateComponents*cmp =[calendercomponents:NSCalendarUnitMinute fromDate:[NSDatedate]];
//分
CGFloatminute =cmp.minute;
6.8.旋轉(zhuǎn)分針
//計算分針角度
CGFloatminuteAngle = (minute *6*M_PI) /180;//旋轉(zhuǎn)分針
self.minuteLayer.transform =
CATransform3DMakeRotation(minuteAngle,0,0,1);
6.9.添加時針
#pragma mark --添加時針
-(void)addHour{CALayer*hourLayer = [[CALayeralloc]init];
[self.view.layeraddSublayer:hourLayer];
hourLayer.bounds=CGRectMake(0,0,3,65);
hourLayer.position=
CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2);
hourLayer.anchorPoint=CGPointMake(0.5,1);
hourLayer.backgroundColor= [UIColorcyanColor].CGColor;
self.hourLayer= hourLayer;
}
6.10.獲得當前時間的小時
//獲得一個系統(tǒng)處理時間對象
NSCalendar*calender = [NSCalendarcurrentCalendar];//獲得 時間對象 來獲得當前的 時分秒
NSDateComponents*cmp =[calendercomponents:NSCalendarUnitHour fromDate:[NSDatedate]];
//時
CGFloathour =cmp.hour;
6.11.旋轉(zhuǎn)時針
//計算時針角度
CGFloathourAngle = (hour *30*M_PI) /180;CGFloatminute2HourAngle = (minute *0.5*M_PI) /180;
hourAngle += minute2HourAngle;
//旋轉(zhuǎn)時針
self.hourLayer.transform =
CATransform3DMakeRotation(hourAngle,0,0,1);
7.核心動畫7.1.動畫簡介
1.Core Animation,中文翻譯為核心動畫,它是一組非常強大的動畫處理API,使用它能做
出非常炫麗的動畫效果,而且往往是事半功倍。也就是說,使用少量的代碼就可以實現(xiàn)非常
強大的功能。
2.Core Animation可以用在Mac OS X和iOS平臺。
3.Core Animation的動畫執(zhí)行過程都是在后臺操作的,不會阻塞主線程。
要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。
7.2.核心動畫繼承結(jié)構
7.3.核心動畫使用步驟
1.如果不是xcode5之后的版本,使用它需要先添加QuartzCore.framework和引入對應的框架
2.開發(fā)步驟:
1.首先得有CALayer
2.初始化一個CAAnimation對象,并設置一些動畫相關屬性
3.通過調(diào)用CALayer的addAnimation:forKey:方法,增加CAAnimation對象到CALayer
中,這樣就能開始執(zhí)行動畫了
4.通過調(diào)用CALayer的removeAnimationForKey:方法可以停止CALayer中的動畫
7.4.怎樣才能產(chǎn)生動畫
事物產(chǎn)生了位移,縮放,旋轉(zhuǎn),透明度變化,才會產(chǎn)生動畫。
所以可動畫屬性
位置 :position / transform.translation縮放 :transform.scale
旋轉(zhuǎn) :transform.rotation
透明度 :opacity
7.5.基本動畫CABasicAnimation
CABasicAnimation*animation = [CABasicAnimationanimationWithKeyPath:@"position"];
animation.toValue = [NSValue
valueWithCGPoint:CGPointMake(300,350)];
//動畫的執(zhí)行時間
animation.duration =1.0;
//動畫的填充模式
animation.fillMode = kCAFillModeForwards;//當動畫執(zhí)行完成后 是否移除
animation.removedOnCompletion =NO;
[self.redLayer addAnimation:animation forKey:key];
7.6.關鍵幀動畫CAKeyframeAnimation
//創(chuàng)建一個關鍵幀動畫
CAKeyframeAnimation*animation = [CAKeyframeAnimationanimation];
animation.keyPath=@"position";
animation.duration=2;
NSValue*value1 = [NSValuevalueWithCGPoint:CGPointMake(50,50)];
NSValue*value2 = [NSValuevalueWithCGPoint:CGPointMake(250,50)];
NSValue*value3 = [NSValuevalueWithCGPoint:CGPointMake(250,300)];
NSValue*value4 = [NSValuevalueWithCGPoint:CGPointMake(50,300)];
animation.values=@[value1,value2,value3,value4,value1];
[self.myLayeraddAnimation:animationforKey:nil];
7.7.動畫組CAAnimationGroup
-(void)touchesBegan:(NSSet *)touches
withEvent:(UIEvent*)event{
//移動動畫
CABasicAnimation*translate = [CABasicAnimationanimationWithKeyPath:@"position"];
translate.toValue= [NSValuevalueWithCGPoint:CGPointMake(100,100)];
//縮放動畫
CABasicAnimation*scale = [CABasicAnimationanimationWithKeyPath:@"transform.scale"];
scale.toValue=@0.5;//旋轉(zhuǎn)動畫
CABasicAnimation*rotation = [CABasicAnimationanimationWithKeyPath:@"transform.rotation"];
rotation.toValue=@(M_PI);//把以上動畫添加到動畫組中
CAAnimationGroup*animationGroup = [CAAnimationGroupanimation];
animationGroup.animations=@[translate,scale,rotation];
//設置動畫的時間animationGroup.duration=2.0;//動畫組是否移動動畫屬性 失效
//animationGroup.removedOnCompletion = NO;
animationGroup.repeatCount=MAXFLOAT;
animationGroup.autoreverses=YES;
7.8.轉(zhuǎn)場動畫CATransition
[self.myLayeraddAnimation:animationGroupforKey:nil];
}
//添加轉(zhuǎn)場動畫UIImageView會自動按照轉(zhuǎn)場動畫來加載下一張圖片
CATransition*animation = [CATransitionanimation];
animation.duration=1;
animation.type=@"pageCurl";
animation.subtype=kCATransitionFromTop;
[self.imageView.layeraddAnimation:animationforKey:nil];
7.9.添加動畫到CALayer對象addAniamtion:forKey:
7.10.避免重復添加動畫1.addAniamtion:forKey:這里要給一個Key
2.判斷當前l(fā)ayer是否已經(jīng)添加了此動畫animationForKey:
7.11. CALayer上動畫的暫停
[self.imageView.layeraddAnimation:animationforKey:nil];
NSString *key =@"myPosition";if([self.redLayer animationForKey:key] !=nil)return;
#pragma mark暫停CALayer的動畫-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
//讓CALayer的時間停止走動layer.speed = 0.0;
//讓CALayer的時間停留在pausedTime這個時刻
layer.timeOffset = pausedTime;
}
7.12. CALayer上動畫的恢復
#pragma mark恢復CALayer的動畫-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = layer.timeOffset;
// 1.讓CALayer的時間繼續(xù)行走
layer.speed = 1.0;
// 2.取消上次記錄的停留時刻
layer.timeOffset = 0.0;
// 3.取消上次設置的時間layer.beginTime = 0.0;
// 4.計算暫停的時間(這里也可以用CACurrentMediaTime()-pausedTime)
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime()
fromLayer:nil] - pausedTime;
// 5.設置相對于父坐標系的開始時間(往后退timeSincePause)
layer.beginTime = timeSincePause;
}
7.13.動畫的其它設置
7.13.1. duration
動畫時長
7.13.2. fillMode
填充模式
7.13.3. removeOnCompletion
動畫完成后是否刪除動畫
7.13.4. repeatCount
重復次數(shù)
7.13.5. autoreverse
播放之后原路返回
7.13.6. delegate
動畫代理
7.13.7. repeatDuration
重復時間
7.13.8. beginTime
可以用來設置動畫延遲執(zhí)行時間,若想延遲2s,就設置為CACurrentMediaTime()+2,CACurrentMediaTime()為圖層的當前時間
7.13.9. timingFunction
速度控制函數(shù),控制動畫運行的節(jié)奏
8. UIView封裝的動畫與核心動畫區(qū)別8.1.UIView封裝的動畫
[UIViewanimateWithDuration:1.0animations:^{self.redView.transform=
CGAffineTransformTranslate(self.redView.transform,100,100);
}];
[UIViewtransitionWithView:self.viewduration:1.0options:UIViewAnimationOptionRepeat animations:^{
}completion:^(BOOLfinished) {
}];
8.2.UIView封裝的動畫與核心動畫的區(qū)別核心動畫一切都是假象。位置并沒有發(fā)生改變。
UIView動畫是位置發(fā)生了改變
9.定時器介紹
9.1.NSTimer
1.系統(tǒng)計時器。2.使用
[NSTimerscheduledTimerWithTimeInterval:1.0target:selfselector:@selector(timerun)userInfo:nilrepeats:YES];
- (void)timerun{NSLog(@"time run");
}
9.2.CADisplayLink
1.CADisplayLink是一種以屏幕刷新頻率觸發(fā)的時鐘機制,每秒鐘執(zhí)行大約60次左右2.CADisplayLink是一個計時器,可以使繪圖代碼與視圖的刷新頻率保持同步,而NSTimer
無法確保計時器實際被觸發(fā)的準確時間
3.使用方法:
定義CADisplayLink并制定觸發(fā)調(diào)用方法
將顯示鏈接添加到主運行循環(huán)隊列
9.3.dispatch_after延遲
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.1* NSEC_PER_SEC)), dispatch_get_main_queue(),
^{});
10.轉(zhuǎn)盤效果10.1.布局界面
1.自定義xib
2.按照UI給的背景圖片布局-Image屬性
10.2.核心動畫旋轉(zhuǎn)界面
CABasicAnimation*anim = [CABasicAnimationanimation];
anim.keyPath=@"transform.rotation";
anim.toValue=@(M_PI*2*3);
anim.duration=0.5;
anim.delegate=self;
[self.wheelViews.layeraddAnimation:animforKey:@"wheel"];
10.3. awakeFromNib添加按鈕
for(inti =0;i <12;i++){WheelButton*button = [WheelButton
buttonWithType:UIButtonTypeCustom];
button.bounds=CGRectMake(0,0,68,143);
button.layer.position=self.center;
button.layer.anchorPoint=CGPointMake(0.5,1);
[self.wheelViewaddSubview:button];
}
10.4.旋轉(zhuǎn)按鈕CGAffineTransformRotate
#define angle2Arc(angle) (angle * M_PI /180)
button.transform=CGAffineTransformRotate(button.transform,angle2Arc(i *30) );
10.5.設置按鈕選中時背景色
10.6.設置按鈕點擊事件—點擊選中
[buttonsetBackgroundImage:[UIImageimageNamed:@"LuckyRototeSelected"]forState:UIControlStateSelected];
[buttonaddTarget:selfaction:@selector(btnClick:)forControlEvents:UIControlEventTouchDown];
- (void)btnClick:(UIButton*)btn{
btn.selected=YES;
}
10.7.取消上一個按鈕選中
- (void)btnClick:(UIButton*)btn{self.selectedBtn.selected=NO;
btn.selected=YES;self.selectedBtn= btn;
}
#pragma mark --懶加載定時器
- (CADisplayLink*)link{if(_link==nil){
_link= [CADisplayLinkdisplayLinkWithTarget:selfselector:@selector(updateView)];
[_linkaddToRunLoop:[NSRunLoopmainRunLoop]forMode:NSDefaultRunLoopMode];
}
return_link;
}
#pragma mark --旋轉(zhuǎn)界面
- (void)updateView{self.wheelView.transform=
CGAffineTransformRotate(self.wheelView.transform,angle2Arc(45/60.0));
}
- (void)startSlowRun{self.link.paused=NO;
}
- (void)stopSlowRun{
self.link.paused=YES;
}
10.9.添加按鈕上正常狀態(tài)的圖片
UIImage*normalImage = [UIImageimageNamed:@"LuckyAstrology"];
CGFloatnormalW = normalImage.size.width/12;CGFloatnormalH = normalImage.size.height;
CGFloatscale = [UIScreenmainScreen].scale;if(scale >2) scale =2;
normalW = normalW * scale;
normalH = normalH * scale;
CGFloatnormalX = i * normalW;CGFloatnormalY =0;
CGImageRefnormalItemImage =CGImageCreateWithImageInRect(normalImage.CGImage,CGRectMake(normalX, normalY, normalW, normalH));
[buttonsetImage:[UIImageimageWithCGImage:normalItemImage]forState:UIControlStateNormal];
10.10.添加按鈕上選中狀態(tài)的圖片
UIImage *selectedImage = [UIImage
imageNamed:@"LuckyAstrologyPressed"];
CGFloat selectedW = selectedImage.size.width /12;CGFloatselectedH = selectedImage.size.height;
selectedW = selectedW * scale;
selectedH = selectedH * scale;
CGFloatselectedX = i * selectedW;
CGFloatselectedY =0;
CGImageRefselectedItemImage =CGImageCreateWithImageInRect(selectedImage.CGImage,CGRectMake(selectedX, selectedY, selectedW, selectedH));
[buttonsetImage:[UIImageimageWithCGImage:selectedItemImage]forState:UIControlStateSelected];
10.11.自定義按鈕—解決圖片布局問題
- (CGRect)imageRectForContentRect:(CGRect)contentRect{CGFloatx = (contentRect.size.width-40) *0.5;
returnCGRectMake(x,20,40,47);
}
10.12.自定義按鈕—去掉高亮
10.13.開始選號—核心動畫
- (void)setHighlighted:(BOOL)highlighted{}
- (IBAction)startRun:(UIButton*)sender {
staticNSString*key =@"rotation";if([self.wheelView.layeranimationForKey:key])return;CABasicAnimation*animation = [CABasicAnimation
animationWithKeyPath:@"transform.rotation"];
animation.toValue=@(M_PI*2*3);
animation.duration=4;
animation.delegate=self;
[self.wheelView.layeraddAnimation:animation
forKey:key];
}
10.14.選號動畫結(jié)束后停在選中按鈕位置
- (void)animationDidStop:(CAAnimation*)anim
finished:(BOOL)flag{
CGFloatangle =atan2(self.selectedBtn.transform.b,self.selectedBtn.transform.a);
self.wheelView.transform=CGAffineTransformMakeRotation(-angle);
}