神奇的CAReplicatorLayer

文檔描述:

The CAReplicatorLayer class creates a specified number of copies of its sublayers (the source layer), each copy potentially having geometric, temporal and color transformations applied to it.

簡介

  • 支持系統(tǒng):>=iOS3.0。
  • 文檔釋義:CAReplicatorLayer類可用來從layer源高效復(fù)制多個實體對象卷哩,每個實體對象都可以擁有幾何形狀将谊、顏色、時間層次上的不同轉(zhuǎn)換县耽。
  • 實際應(yīng)用: 加載動畫狡刘、鏡像layer的生成基协。

使用示例1:實現(xiàn)一個鏡像反射效果

1.創(chuàng)建一個模板層

  /*        創(chuàng)建一個模板層 CAReplicatorLayer會按照一定的規(guī)則“克隆”這個模板         */
  CAShapeLayer *shape = [CAShapeLayer layer];
  shape.frame = CGRectMake(0, 0, 80, 80);
  /*        繪制模板的形狀         */
  shape.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 80, 80)].CGPath;
  /*        模板的填充顏色         */
  shape.fillColor = [UIColor redColor].CGColor;
  shape.opacity = 0.0;
  /*        創(chuàng)建所有的子層的動畫組(也可以是單個動畫)         */
  CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
  /*        動畫組元素         */
  animationGroup.animations = @[[self alphaAnimation],[self scaleAnimation]];
  /*        動畫執(zhí)行時間         */
  animationGroup.duration = 4.0;
  animationGroup.autoreverses = NO;
  animationGroup.repeatCount = HUGE;
  /*        給模板層添加動畫 實質(zhì)上也是給每個CAReplicatorLayer子層添加動畫         */
  [shape addAnimation:animationGroup forKey:@"animationGroup"];
  /*        創(chuàng)建CAReplicatorLayer對象         */
  CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
  replicatorLayer.frame = self.containerView.bounds;
  /*        設(shè)置每個元素的添加間隔時間         */
  replicatorLayer.instanceDelay = 0.5;
  /*        設(shè)置每元素個數(shù)         */
  replicatorLayer.instanceCount = 8;
  /*        給CAReplicatorLayer對象的子層添加轉(zhuǎn)換規(guī)則 這里決定了子層的布局         */
  replicatorLayerY.instanceTransform = CATransform3DTranslate(CATransform3DIdentity, 0, radius+between, 0);
  /*        添加子層         */
  [replicatorLayer addSublayer:shape];

Note:在這里惋鸥,大家可以根據(jù)需要添加不同的動畫元素或者不添加任何動畫揩慕,該用法多用于實現(xiàn)加載提示視圖的動畫制作。

2.實現(xiàn)某個視圖的反射效果

我們首先繼承UIView創(chuàng)建一個子類拴鸵,在子類的+(Class)layerClass方法中設(shè)置當(dāng)前視圖對象的layer為CAReplicatorLayer對象:

  + (Class)layerClass{
   return [CAReplicatorLayer class];
  }

然后在創(chuàng)建該子類的對象時對self.layer進行設(shè)置相關(guān)參數(shù):

- (void)setup{
/*        獲取當(dāng)前的layer 實際上為CAReplicatorLayer對象         */
CAReplicatorLayer *layer = (CAReplicatorLayer *)self.layer;
layer.instanceCount = 2;
layer.anchorPoint = CGPointMake(0.5, 0.5);

/*        創(chuàng)建3D轉(zhuǎn)換效果         */
CATransform3D transform = CATransform3DIdentity;
CGFloat verticaloffset = self.bounds.size.height  ;
transform = CATransform3DTranslate(transform, 0, verticaloffset, 0);

/*        設(shè)置Y軸鏡面反射         */
transform = CATransform3DScale(transform, 1, -1, 0);
transform = CATransform3DRotate(transform, -M_PI / 4, 1, 0, 0);
layer.instanceTransform  = transform;
/*        鏡面的透明度 越低顯示越清晰 因為是鏡面效果         */
layer.instanceAlphaOffset = -0.1;
}

效果圖如下:


鏡像層.png

示例2:CAReplicatorLayer作為核心技術(shù)實現(xiàn)加載動畫。

1.首先樟凄,創(chuàng)建一個UIView的子類聘芜,并暴露相關(guān)方法:

@interface JHHJView : UIView
/*        顯示加載動畫 并添加到父視圖上         */
+ (void)showLoadingOnView:(UIView *)superView Type:(JHHJViewType)type;
/*        顯示動畫 并添加在主窗口上         */
+ (void)showLoadingOnTheKeyWindowWithType:(JHHJViewType)type;
/*        停止動畫         */
+ (void)hideLoading;
/*        設(shè)置動畫背景色(全屏背景色)         */
+ (void)backgroudColor:(UIColor *)color;
/*        設(shè)置中心視圖的動畫背景顏色 默認透明色         */
+ (void)centerBGViewBackgroudColor:(UIColor *)color;

2.并且聲明了一個枚舉類型:該枚舉類型代表著加載動畫類型。

typedef  NS_ENUM(NSInteger,JHHJViewType){
/**
 *  線性動畫
 */
JHHJViewTypeSingleLine = 0,

/**
 *  方形點動畫
 */
JHHJViewTypeSquare = 1,

/**
 *  三角形運動動畫
 */
JHHJViewTypeTriangleTranslate = 2,

/**
 *  原型視圖裁剪動畫
 */
JHHJViewTypeClip
};

3.在.m文件中缝龄,該類擁有的成員變量如下:

@interface JHHJView ()
//中心背景視圖
@property (nonatomic,strong)JHHJCenterBGView *centerBGView;
//計時器
@property (nonatomic,strong)NSTimer * clipTimer;
//層數(shù)組
@property (nonatomic,strong)NSMutableArray * clipLayerArr;
//計時器計量數(shù)
@property (nonatomic,assign) long long currentTimerIndex;
//背景層
@property (nonatomic,strong) CAShapeLayer *bgLayer;
@end

4.然后汰现,設(shè)置以單例的方式創(chuàng)建該類的對象:

/**
 *  對象單例化
*
 *  @return 單例對象
*/
+ (JHHJView *)shareInstanceJHHJView{
static JHHJView * instance = nil;
if (!instance) {
    instance                     = [[JHHJView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    instance.centerBGView        = [[JHHJCenterBGView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    instance.centerBGView.center = CGPointMake(K_IOS_WIDTH / 2, K_IOS_HEIGHT/2);
    [instance addSubview:instance.centerBGView];
}
return instance;
}

5.動畫的實現(xiàn)如下:

/**
 *  展示動畫視圖 并添加到依賴視圖上
 *
*  @param superView 依賴的父視圖
*  @param type      動畫樣式
*/
+ (void)showLoadingOnView:(UIView *)superView Type:(JHHJViewType)type{
/*        在顯示前  先從父視圖移除當(dāng)前動畫視圖         */
JHHJView *instance = [[self class] shareInstanceJHHJView];
[[self class] hideLoading];
/*        顯示前 先將動畫圖層從中心視圖上移除         */
for (CALayer *layer in instance.centerBGView.layer.sublayers) {
    [layer removeFromSuperlayer];
}
/*        按照type初始化動畫         */
switch (type) {
    case JHHJViewTypeSingleLine:
    {
        CALayer *layer = [instance lineAnimation];
        layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 - 25, CGRectGetHeight(instance.centerBGView.frame)/2);
        [instance.centerBGView.layer addSublayer:layer];
    }break;
        
    case JHHJViewTypeSquare:
    {
        CALayer *layer = [[self class] qurareAnimation];
        layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2, CGRectGetHeight(instance.centerBGView.frame)/2);
        [instance.centerBGView.layer addSublayer:layer];
    }break;
    case JHHJViewTypeTriangleTranslate:
    {
        CALayer *layer = [[self class] triangleAnimation];
        layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 - 18, CGRectGetHeight(instance.centerBGView.frame)/2 - 15);
        [instance.centerBGView.layer addSublayer:layer];
    }break;
    case JHHJViewTypeClip:
    {
        
        CALayer *layer = [[self class] clipAnimation];
        layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 , CGRectGetHeight(instance.centerBGView.frame)/2 - 15);
        [instance.centerBGView.layer addSublayer:layer];
        
    }break;
    default:
        break;
}
[superView addSubview:instance];
}

6.下面來具體實現(xiàn)其中一個動畫,以三角形旋轉(zhuǎn)動畫為例:

/**
*  三角形運動動畫
 *
*  @return 動畫實例對象
 */
+ (CALayer *)triangleAnimation{
/*        基本間距確定及模板層的創(chuàng)建         */
CGFloat radius                     = 50/4.0;
CGFloat transX                     = 50 - radius;
CAShapeLayer *shape                = [CAShapeLayer layer];
shape.frame                        = CGRectMake(0, 0, radius, radius);
shape.path                         = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, radius, radius)].CGPath;
shape.strokeColor                  = [UIColor redColor].CGColor;
shape.fillColor                    = [UIColor redColor].CGColor;
shape.lineWidth                    = 1;
[shape addAnimation:[JHHJAnimation rotateAnimation] forKey:@"rotateAnimation"];

/*        創(chuàng)建克隆層         */
CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
replicatorLayer.frame              = CGRectMake(0, 0, radius, radius);
replicatorLayer.instanceDelay      = 0.0;
replicatorLayer.instanceCount      = 3;
CATransform3D trans3D              = CATransform3DIdentity;
trans3D                            = CATransform3DTranslate(trans3D, transX, 0, 0);
trans3D                            = CATransform3DRotate(trans3D, 120.0*M_PI/180.0, 0.0, 0.0, 1.0);
replicatorLayer.instanceTransform  = trans3D;
[replicatorLayer addSublayer:shape];
return replicatorLayer;
}

流程如上叔壤,效果圖如下:

loading......

想要了解更多瞎饲,源碼在這里哦......

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市炼绘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疟呐,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機示惊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門录择,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事菱皆。” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長臣淤。 經(jīng)常有香客問我按厘,道長卿堂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任妻导,我火速辦了婚禮暑脆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己鲤孵,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布廊散。 她就那樣靜靜地躺著,像睡著了一般胁澳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上败明,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機與錄音沥潭,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昌抠,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起磺芭,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后荧关,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體加勤,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了顿苇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡贡定,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出签杈,到底是詐尸還是另有隱情择卦,我是刑警寧澤秕噪,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站盐杂,受9級特大地震影響厉斟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜究飞,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一筑累、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贱田,春花似錦男摧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鱼冀。三九已至瑞妇,卻和暖如春稿静,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辕狰。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工改备, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蔓倍。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓悬钳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親柬脸。 傳聞我的和親對象是個殘疾皇子他去,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件倒堕、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,120評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,285評論 25 707
  • 水滿杯中酒灾测, 悲喜倒一壺。 觥籌有人夢垦巴, 此醉無人醒媳搪。
    月光徐風(fēng)閱讀 108評論 0 0
  • 記錄一下(剛開始適配iOS11的時候用到的,出處都不記得骤宣。秦爆。。) 1.podfile iOS11添加下面的內(nèi)容到P...
    寶寶丶菲閱讀 463評論 0 0
  • 西湖邊 沒走出去也不會看到憔披,有天研說:我買了新車等限,走,我?guī)闳ノ骱碉L(fēng)芬膝,我說好望门,我們?nèi)罟蹋蚁矚g那的陡坡锰霜,一陣...
    君君之閱讀 153評論 0 0