核心動畫

Transform field value key paths!

position.x

position.y


1. CALayer1.1.什么是CALayer

是圖層。

1.2.CALayer有什么用用來做界面的顯示。

1.3.CALayer原理

當UIView需要顯示到屏幕上時,會調用drawRect:方法進行繪圖。并且會將所有內容

繪制在自己的圖層上,繪圖完畢后,系統會將圖層拷貝到屏幕上,于是就完成了UIView的

顯示。

1.4.CALayer的基本使用

陰影shadow

圓角corner

邊框border

透明度opacity

背景色backgroundColor內容contents

位置大小frame裁剪maskToBounds

1.5.注意

設置圓角半徑不會影響內容,除非剪切。

可以通過拖一個UIImageView組件來檢測

1.6.CALayer所屬框架,并且介紹類型介紹

數據類型是QuartzCore框架中的。

為了跨平臺,跨了哪些平臺?

Mac系統 iOS系統

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。自動手動創建添加到CALayer

上的才不是根層layer

4. CALayer的transform屬性根層:沒有動畫,需要自己做一個動畫。

需要用KVC做對比。

KVC設置旋轉屬性在時鐘案例中,旋轉到30秒的時候會出現問題。

有make和 沒有make的區別?

有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是系統時間類

5.1.2.獲得系統當前時間

5.2.NSDateFormatter5.2.1.介紹

系統時間格式化類

NSDate*date = [NSDatedate];

5.2.2. NSDate轉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轉NSDate

NSString*time =@"2015-11-29 10:18:07";

NSDateFormatter*formatter = [[NSDateFormatteralloc]init];

formatter.dateFormat=@"yyyy-MM-dd HH:mm:ss";

//設置時區

NSTimeZone*GTMzone = [NSTimeZonetimeZoneForSecondsFromGMT:0];

[formattersetTimeZone:GTMzone];NSDate*date = [formatterdateFromString:time];NSLog(@"%@",date);

5.3.NSCalendar5.3.1.介紹

是系統時間工具類,用于獲取時間的各個信息。并且可以做時間比較

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.添加定時器每秒調用一次

//通過定時器的方式來使 時分秒針旋轉起來

-(void)startRun{

[NSTimerscheduledTimerWithTimeInterval:1target:self

selector:@selector(updateTime)userInfo:nilrepeats:YES];

}

6.4.獲得當前時間的秒數

//獲得一個系統處理時間對象

NSCalendar *calender = [NSCalendar currentCalendar];

//獲得 時間對象 來獲得當前的 時分秒

NSDateComponents *cmp =[calender

components:NSCalendarUnitSecond fromDate:[NSDate date]];

//秒

CGFloat second = cmp.second;

6.5.旋轉秒針

//計算秒針角度

CGFloatangle = (second *6*M_PI) /180;//旋轉秒針

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.獲得當前時間的分鐘數

//獲得一個系統處理時間對象

NSCalendar*calender = [NSCalendarcurrentCalendar];

//獲得 時間對象 來獲得當前的 時分秒

NSDateComponents*cmp =[calendercomponents:NSCalendarUnitMinute fromDate:[NSDatedate]];

//分

CGFloatminute =cmp.minute;

6.8.旋轉分針

//計算分針角度

CGFloatminuteAngle = (minute *6*M_PI) /180;//旋轉分針

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.獲得當前時間的小時

//獲得一個系統處理時間對象

NSCalendar*calender = [NSCalendarcurrentCalendar];//獲得 時間對象 來獲得當前的 時分秒

NSDateComponents*cmp =[calendercomponents:NSCalendarUnitHour fromDate:[NSDatedate]];

//時

CGFloathour =cmp.hour;

6.11.旋轉時針

//計算時針角度

CGFloathourAngle = (hour *30*M_PI) /180;CGFloatminute2HourAngle = (minute *0.5*M_PI) /180;

hourAngle += minute2HourAngle;

//旋轉時針

self.hourLayer.transform =

CATransform3DMakeRotation(hourAngle,0,0,1);

7.核心動畫7.1.動畫簡介

1.Core Animation,中文翻譯為核心動畫,它是一組非常強大的動畫處理API,使用它能做

出非常炫麗的動畫效果,而且往往是事半功倍。也就是說,使用少量的代碼就可以實現非常

強大的功能。

2.Core Animation可以用在Mac OS X和iOS平臺。

3.Core Animation的動畫執行過程都是在后臺操作的,不會阻塞主線程。

要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。

7.2.核心動畫繼承結構

7.3.核心動畫使用步驟

1.如果不是xcode5之后的版本,使用它需要先添加QuartzCore.framework和引入對應的框架

2.開發步驟:

1.首先得有CALayer

2.初始化一個CAAnimation對象,并設置一些動畫相關屬性

3.通過調用CALayer的addAnimation:forKey:方法,增加CAAnimation對象到CALayer

中,這樣就能開始執行動畫了

4.通過調用CALayer的removeAnimationForKey:方法可以停止CALayer中的動畫

7.4.怎樣才能產生動畫

事物產生了位移,縮放,旋轉,透明度變化,才會產生動畫。

所以可動畫屬性

位置 :position / transform.translation縮放 :transform.scale

旋轉 :transform.rotation

透明度 :opacity

7.5.基本動畫CABasicAnimation

CABasicAnimation*animation = [CABasicAnimationanimationWithKeyPath:@"position"];

animation.toValue = [NSValue

valueWithCGPoint:CGPointMake(300,350)];

//動畫的執行時間

animation.duration =1.0;

//動畫的填充模式

animation.fillMode = kCAFillModeForwards;//當動畫執行完成后 是否移除

animation.removedOnCompletion =NO;

[self.redLayer addAnimation:animation forKey:key];

7.6.關鍵幀動畫CAKeyframeAnimation

//創建一個關鍵幀動畫

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;//旋轉動畫

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.轉場動畫CATransition

[self.myLayeraddAnimation:animationGroupforKey:nil];

}

//添加轉場動畫UIImageView會自動按照轉場動畫來加載下一張圖片

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.判斷當前layer是否已經添加了此動畫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的時間繼續行走

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

重復次數

7.13.5. autoreverse

播放之后原路返回

7.13.6. delegate

動畫代理

7.13.7. repeatDuration

重復時間

7.13.8. beginTime

可以用來設置動畫延遲執行時間,若想延遲2s,就設置為CACurrentMediaTime()+2,CACurrentMediaTime()為圖層的當前時間

7.13.9. timingFunction

速度控制函數,控制動畫運行的節奏

8. UIView封裝的動畫與核心動畫區別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封裝的動畫與核心動畫的區別核心動畫一切都是假象。位置并沒有發生改變。

UIView動畫是位置發生了改變

9.定時器介紹

9.1.NSTimer

1.系統計時器。2.使用

[NSTimerscheduledTimerWithTimeInterval:1.0target:selfselector:@selector(timerun)userInfo:nilrepeats:YES];

- (void)timerun{NSLog(@"time run");

}

9.2.CADisplayLink

1.CADisplayLink是一種以屏幕刷新頻率觸發的時鐘機制,每秒鐘執行大約60次左右2.CADisplayLink是一個計時器,可以使繪圖代碼與視圖的刷新頻率保持同步,而NSTimer

無法確保計時器實際被觸發的準確時間

3.使用方法:

定義CADisplayLink并制定觸發調用方法

將顯示鏈接添加到主運行循環隊列

9.3.dispatch_after延遲

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,

(int64_t)(0.1* NSEC_PER_SEC)), dispatch_get_main_queue(),

^{});

10.轉盤效果10.1.布局界面

1.自定義xib

2.按照UI給的背景圖片布局-Image屬性

10.2.核心動畫旋轉界面

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.旋轉按鈕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 --旋轉界面

- (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.添加按鈕上正常狀態的圖片

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.添加按鈕上選中狀態的圖片

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.選號動畫結束后停在選中按鈕位置

- (void)animationDidStop:(CAAnimation*)anim

finished:(BOOL)flag{

CGFloatangle =atan2(self.selectedBtn.transform.b,self.selectedBtn.transform.a);

self.wheelView.transform=CGAffineTransformMakeRotation(-angle);

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容