這篇文章意在做一些簡單的Animation Category 方便需初學(xué)者使用和有興趣間接去了解一下CALayer Core Animation 看到網(wǎng)上很多博文都寫的很好 有興趣可以多了解一下 都不是很難 主要是一些API的理解和調(diào)試運用 理解了就很簡單了
iOS核心動畫
Demo寫了三個類別 分別是在項目中有使用的一些簡單動畫實現(xiàn)(呼吸、心跳径荔、繞軸XYZ旋轉(zhuǎn)督禽、系統(tǒng)支持的一些水波紋、翻書总处、立方狈惫、翻轉(zhuǎn)等...)
關(guān)于Core Animation完整的詳細(xì)資料,這里有一份詳細(xì)的介紹(由海水的味道翻譯)
圖層是Core Animation的核心,那么什么是CALayer
OC中,基本上所有的控件都是UIView,而UIView之所以能夠在屏幕上顯示,因為每一個UIView內(nèi)部都默認(rèn)關(guān)聯(lián)一個CALayer.
當(dāng)UIView將要顯示到屏幕上的時候,會調(diào)用drawRect:進(jìn)行繪圖,將所有的內(nèi)容繪制在自己的圖層上,繪制完畢后,系統(tǒng)會將圖層copy到屏幕上.其實也就是說UIView本身不具備顯示的功能,是因為有了Layer才有顯示的功能,所以UIView和CALayer相互依賴.
CALayer 基礎(chǔ)介紹
一些動畫簡單的使用例子 具體可以看文末demo
/** 心跳縮放動畫*/
- (void)beginHeartbeatAnimation{
CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
opacityAnimation.fromValue = @0.8;
opacityAnimation.toValue = @1.2;
opacityAnimation.duration = 0.5;
opacityAnimation.autoreverses = YES;
opacityAnimation.repeatCount = INFINITY;
opacityAnimation.fillMode = kCAFillModeBoth;
opacityAnimation.removedOnCompletion = NO;
[self addAnimation:opacityAnimation forKey:@"beginHeartbeatAnimation"];
}
- (void)removeHeartbeatAnimation{
[self removeAnimationForKey:@"beginHeartbeatAnimation"];
}
跳動.gif
/**
翻轉(zhuǎn)動畫
@param direction 方向
@param duration 時間
@param isReverse 自動反轉(zhuǎn)
@param repeatCount 重復(fù)次數(shù)
*/
-(CAAnimation *)reversAnimationWithDirection:(AnimReverDirection)direction
duration:(NSTimeInterval)duration
isReverse:(BOOL)isReverse
repeatCount:(NSUInteger)repeatCount
timingFuncName:(NSString *)timingFuncName{
NSString *key = @"reversAnim";
if([self animationForKey:key]!=nil){
[self removeAnimationForKey:key];
}
NSString *directionStr = nil;
if(AnimReverDirectionX == direction)directionStr=@"x";
if(AnimReverDirectionY == direction)directionStr=@"y";
if(AnimReverDirectionZ == direction)directionStr=@"z";
//創(chuàng)建普通動畫
CABasicAnimation *reversAnim = [CABasicAnimation animationWithKeyPath:[NSString stringWithFormat:@"transform.rotation.%@",directionStr]];
//起點值
reversAnim.fromValue=@(0);
//終點值
reversAnim.toValue = @(M_PI_2);
//時長
reversAnim.duration = duration;
//自動反轉(zhuǎn)
reversAnim.autoreverses = isReverse;
//完成刪除
reversAnim.removedOnCompletion = YES;
//重復(fù)次數(shù)
reversAnim.repeatCount = repeatCount;
//添加
[self addAnimation:reversAnim forKey:key];
return reversAnim;
}
翻轉(zhuǎn).gif
/**
* 轉(zhuǎn)場動畫
*
* @param animType 轉(zhuǎn)場動畫類型
* @param subType 轉(zhuǎn)動動畫方向
* @param curve 轉(zhuǎn)動動畫曲線
* @param duration 轉(zhuǎn)動動畫時長
*
* @return 轉(zhuǎn)場動畫實例
*/
-(CATransition *)transitionWithAnimType:(TransitionAnimType)animType
subType:(TransitionSubType)subType
curve:(TransitionCurve)curve
duration:(CGFloat)duration;
/**
* 轉(zhuǎn)場動畫
*
* @param animType 轉(zhuǎn)場動畫類型
* @param subType 轉(zhuǎn)動動畫方向
* @param curve 轉(zhuǎn)動動畫曲線
* @param duration 轉(zhuǎn)動動畫時長
*
* @return 轉(zhuǎn)場動畫實例
*/
-(CATransition *)transitionWithAnimType:(TransitionAnimType)animType
subType:(TransitionSubType)subType
curve:(TransitionCurve)curve
duration:(CGFloat)duration{
NSString *key = @"transition";
if([self animationForKey:key]!=nil){
[self removeAnimationForKey:key];
}
CATransition *transition=[CATransition animation];
//動畫時長
transition.duration=duration;
//動畫類型
transition.type=[self animaTypeWithTransitionType:animType];
//動畫方向
transition.subtype=[self animaSubtype:subType];
//緩動函數(shù)
transition.timingFunction=[CAMediaTimingFunction functionWithName:[self curve:curve]];
//完成動畫刪除
transition.removedOnCompletion = YES;
[self addAnimation:transition forKey:key];
return transition;
}
/*
* 返回動畫曲線
*/
-(NSString *)curve:(TransitionCurve)curve{
//曲線數(shù)組
NSArray *funcNames=@[kCAMediaTimingFunctionDefault,
kCAMediaTimingFunctionEaseIn,
kCAMediaTimingFunctionEaseInEaseOut,
kCAMediaTimingFunctionEaseOut,
kCAMediaTimingFunctionLinear];
return [self objFromArray:funcNames
index:curve
isRamdom:(TransitionCurveRamdom == curve)];
}
/*
* 返回動畫方向
*/
-(NSString *)animaSubtype:(TransitionSubType)subType{
//設(shè)置轉(zhuǎn)場動畫的方向
NSArray *subtypes=@[kCATransitionFromTop,
kCATransitionFromLeft,
kCATransitionFromBottom,
kCATransitionFromRight];
return [self objFromArray:subtypes
index:subType
isRamdom:(TransitionSubtypesFromRamdom == subType)];
}
/*
* 返回動畫類型
*/
-(NSString *)animaTypeWithTransitionType:(TransitionAnimType)type{
//設(shè)置轉(zhuǎn)場動畫的類型
NSArray *animArray=@[@"rippleEffect",
@"suckEffect",
@"pageCurl",
@"oglFlip",
@"cube",
@"reveal",
@"pageUnCurl"];
return [self objFromArray:animArray
index:type
isRamdom:(TransitionAnimTypeRamdom == type)];
}
/*
* 統(tǒng)一從數(shù)據(jù)返回對象
*/
-(id)objFromArray:(NSArray *)array
index:(NSUInteger)index
isRamdom:(BOOL)isRamdom{
NSUInteger count = array.count;
NSUInteger i = isRamdom?arc4random_uniform((u_int32_t)count) : index;
return array[i];
}
轉(zhuǎn)場-水波紋.gif
轉(zhuǎn)場-翻書.gif
轉(zhuǎn)場-正方體.gif