日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS - CALayer 绘图层

發布時間:2025/3/17 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS - CALayer 绘图层 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、CALayer 繪圖層

  • 在 iOS 系統中,你能看得見摸得著的東西基本上都是 UIView,比如一個按鈕、一個文本標簽、一個文本輸入框、一個圖標等等,這些都是 UIView。其實 UIView 之所以能顯示在屏幕上,完全是因為它內部的一個層。在創建 UIView 對象時,UIView 內部會自動創建一個層(即 CALayer 對象),通過 UIView 的 layer 屬性可以訪問這個層。當 UIView 需要顯示到屏幕上時,會調用 drawRect: 方法進行繪圖,并且會將所有內容繪制在自己的層上,繪圖完畢后,系統會將層拷貝到屏幕上,于是就完成了 UIView 的顯示。換句話說,UIView 本身不具備顯示的功能,是它內部的層才有顯示功能。

  • CALayer 的簡單使用

    • CALayer 是被定義在 QuartzCore 框架中的,通過操作 CALayer 對象,可以很方便地調整 UIView 的一些界面屬性,比如:陰影、圓角大小、邊框寬度和顏色等。

2、基本繪圖層屬性設置

  • 1、設置陰影

    self.redView.layer.shadowOpacity = 1; // 陰影不透明度self.redView.layer.shadowOffset = CGSizeMake(10, 10); // 陰影偏移量self.redView.layer.shadowColor = [UIColor yellowColor].CGColor; // 陰影顏色self.redView.layer.shadowRadius = 10; // 陰影圓角半徑
  • 2、圓角半徑

    self.redView.layer.cornerRadius = 75; // 主層半徑
  • 3、邊框

    self.redView.layer.borderWidth = 3; // 邊框寬度self.redView.layer.borderColor = [UIColor blueColor].CGColor; // 邊框顏色
  • 4、imageView 圓角半徑設置

    self.imageView.layer.cornerRadius = 75; // 主層半徑// 超出主層邊框的內容全部裁剪掉,image 在視圖層上self.imageView.layer.masksToBounds = YES; // 是否對非主層裁剪
  • 效果

3、形變屬性設置

3.1 視圖形變

  • 1、單一形變

    // 旋轉/*(CGFloat angle) 旋轉 45 度,需要輸入的參數為弧度,45/180 * M_PI,1 度 = PI/180 弧度*/[UIView animateWithDuration:1 animations:^{self.redView.transform = CGAffineTransformMakeRotation(0.25 * M_PI);}];// 縮放/*(CGFloat sx, CGFloat sy) (1, 2) 寬度和高度的放大倍數*/[UIView animateWithDuration:1 animations:^{self.redView.transform = CGAffineTransformMakeScale(1, 2);}];// 平移/*(CGFloat tx, CGFloat ty) (100, 100) 水平和垂直方向的移動距離*/[UIView animateWithDuration:1 animations:^{self.redView.transform = CGAffineTransformMakeTranslation(100, 100);}];
    • 效果

  • 2、 疊加形變

    // 旋轉 + 縮放[UIView animateWithDuration:1 animations:^{CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(0.25 * M_PI);self.redView.transform = CGAffineTransformScale(rotationTransform, 1.5, 1.5);}];// 旋轉 + 平移[UIView animateWithDuration:1 animations:^{CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(0.25 * M_PI);self.redView.transform = CGAffineTransformTranslate(rotationTransform, 100, 0);}];// 縮放 + 平移[UIView animateWithDuration:1 animations:^{CGAffineTransform scaleTransform = CGAffineTransformMakeScale(1, 1.5);self.redView.transform = CGAffineTransformTranslate(scaleTransform, 100, 0);}];// 旋轉 + 縮放 + 平移[UIView animateWithDuration:1 animations:^{CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(0.25 * M_PI);CGAffineTransform rotationScaleTransform = CGAffineTransformScale(rotationTransform, 1.5, 1.5);self.redView.transform = CGAffineTransformTranslate(rotationScaleTransform, 100, 0);}];
    • 效果

  • 3、累加形變

    // 連續旋轉[UIView animateWithDuration:1 animations:^{self.redView.transform = CGAffineTransformRotate(self.redView.transform, 0.25 * M_PI);}];// 連續縮放[UIView animateWithDuration:1 animations:^{self.redView.transform = CGAffineTransformScale(self.redView.transform, 1.5, 1.5);}];// 連續平移[UIView animateWithDuration:1 animations:^{self.redView.transform = CGAffineTransformTranslate(self.redView.transform, 50, 50);}];
    • 效果

  • 4、還原形變

    // 還原所有形變self.redView.transform = CGAffineTransformIdentity;

3.2 繪圖層形變

  • 1、單一形變

    // 旋轉/*(CGFloat angle) 旋轉 45 度,需要輸入的參數為弧度,45/180 * M_PI,1 度 = PI/180 弧度*/[UIView animateWithDuration:1 animations:^{self.redView.layer.affineTransform = CGAffineTransformMakeRotation(0.25 * M_PI);}];// 縮放/*(CGFloat sx, CGFloat sy) (1, 2) 寬度和高度的放大倍數*/[UIView animateWithDuration:1 animations:^{self.redView.layer.affineTransform = CGAffineTransformMakeScale(1, 2);}];// 平移/*(CGFloat tx, CGFloat ty) (100, 100) 水平和垂直方向的移動距離*/[UIView animateWithDuration:1 animations:^{self.redView.layer.affineTransform = CGAffineTransformMakeTranslation(100, 100);}];// 還原所有形變self.redView.layer.affineTransform = CGAffineTransformIdentity;
    • 效果

  • 2、快速進行繪圖層形變,KVC

    // 旋轉[UIView animateWithDuration:1 animations:^{[self.redView.layer setValue:@(0.25 * M_PI) forKeyPath:@"transform.rotation"];}];// 縮放[UIView animateWithDuration:1 animations:^{[self.redView.layer setValue:@1.5 forKeyPath:@"transform.scale"];}];
    • 效果

  • 3、繪圖層 3D 形變

    // 旋轉/*(CGFloat angle, CGFloat x, CGFloat y, CGFloat z) 旋轉角度,x y z 軸的坐標,為 0 時在此軸上不旋轉*/[UIView animateWithDuration:1 animations:^{self.imageView.layer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);}];// 縮放/*(CGFloat sx, CGFloat sy, CGFloat sz),x y z 軸的縮放倍數*/[UIView animateWithDuration:1 animations:^{self.imageView.layer.transform = CATransform3DMakeScale(0.5, 0.5, 1);}];// 平移/*(CGFloat tx, CGFloat ty, CGFloat tz),x y z 軸的平移量*/[UIView animateWithDuration:1 animations:^{self.imageView.layer.transform = CATransform3DMakeTranslation(100, 100, 0);}];
    • 效果

3.3 獲取形變值

  • 獲取旋轉的角度

    // 根據 transform 獲取旋轉角度CGFloat angle = atan2(self.redView.transform.b, self.redView.transform.a);

4、創建新的繪圖層

  • UIView 內部默認有個 CALayer 對象(層),通過 layer 屬性可以訪問這個層。要注意的是,這個默認的層不允許重新創建,但可以往層里面添加子層。UIView 可以通過 addSubview: 方法添加子視圖,類似地,CALayer 可以通過 addSublayer: 方法添加子層。

  • 1、添加一個簡單的圖層

    // 創建圖層CALayer *myLayer = [CALayer layer];myLayer.frame = CGRectMake(100, 100, 200, 200);myLayer.backgroundColor = [UIColor redColor].CGColor;[self.view.layer addSublayer:myLayer];
    • 效果

  • 2、添加一個顯示圖片的圖層

    // 創建圖層CALayer *myLayer = [CALayer layer];myLayer.frame = CGRectMake(100, 100, 200, 200);myLayer.backgroundColor = [UIColor redColor].CGColor;// 設置圖層內容myLayer.contents = (id)[UIImage imageNamed:@"demo2.jpg"].CGImage;[self.view.layer addSublayer:myLayer];
    • 效果

  • 3、為什么 CALayer 中使用 CGColorRef 和 CGImageRef 這 2 種數據類型,而不用 UIColor 和 UIImage ?

    • 首先要知道:CALayer 是定義在 QuartzCore 框架中的;CGImageRef、CGColorRef 兩種數據類型是定義在 CoreGraphics 框架中的;UIColor、UIImage 是定義在 UIKit 框架中的。
    • 其次,QuartzCore 框架和 CoreGraphics 框架是可以跨平臺使用的,在 iOS 和 Mac OS X 上都能使用,但是 UIKit 只能在 iOS 中使用。
    • 因此,為了保證可移植性,QuartzCore 不能使用 UIImage、UIColor,只能使用 CGImageRef、CGColorRef。
    • 不過很多情況下,可以通過 UIKit 對象的特定方法,得到 CoreGraphics 對象,比如 UIImage 的 CGImage 方法可以返回一個 CGImageRef。
  • 4、UIView 和 CALayer 的選擇

    • 細心的朋友不難發現,其實前面的 2 個效果不僅可以通過添加層來實現,還可以通過添加 UIView 來實現。比如,第 1 個紅色的層可以用一個 UIView 來實現,第 2 個顯示圖片的層可以用一個 UIImageView 來實現。既然 CALayer 和 UIView 都能實現相同的顯示效果,那究竟該選擇誰好呢?
    • 其實,對比 CALayer,UIView 多了一個事件處理的功能。也就是說,CALayer 不能處理用戶的觸摸事件,而 UIView 可以。
    • 所以,如果顯示出來的東西需要跟用戶進行交互的話,用 UIView;如果不需要跟用戶進行交互,用 UIView 或者 CALayer 都可以。
    • 當然,CALayer 的性能會高一些,因為它少了事件處理的功能,更加輕量級。
  • 5、UIView 和 CALayer 的關系

    • UIView 可以通過 subviews 屬性訪問所有的子視圖,類似地,CALayer 也可以通過 sublayers 屬性訪問所有的子層。
    • UIView 可以通過 superview 屬性訪問父視圖,類似地,CALayer 也可以通過 superlayer 屬性訪問父層。
    • 下面再看一張 UIView 和 CALayer 的關系圖,如果兩個 UIView 是父子關系,那么它們內部的 CALayer 也是父子關系。

5、繪圖層隱式動畫屬性

  • 在前面已經提到,每一個 UIView 內部都默認關聯著一個 CALayer,我們可稱這個 Layer 為 Root Layer(根層)。所有的非 Root Layer,也就是手動創建的 CALayer 對象,都存在著隱式動畫。

  • 當對非 Root Layer 的部分屬性進行相應的修改時,默認會自動產生一些動畫效果,這些屬性稱為 Animatable Properties 可動畫屬性。

  • 列舉幾個常見的 Animatable Properties:

    bounds :用于設置 CALayer 的寬度和高度。修改這個屬性會產生縮放動畫。backgroundColor :用于設置 CALayer 的背景色。修改這個屬性會產生背景色的漸變動畫。position :用于設置 CALayer 的位置。修改這個屬性會產生平移動畫。比如:假設一開始 CALayer 的 position 為(100, 100),然后在某個時刻修改為(200, 200),那么整個 CALayer 就會在短時間內從 (100, 100) 這個位置平移到 (200, 200)
  • 1、隱式動畫屬性設置

    self.myLayer.bounds = CGRectMake(0, 0, 100, 100);self.myLayer.backgroundColor = [UIColor greenColor].CGColor;self.myLayer.position = CGPointMake(arc4random_uniform(200) + 20, arc4random_uniform(400) + 50);self.myLayer.transform = CATransform3DMakeRotation(arc4random_uniform(360), 0, 0, 1);
    • 效果

  • 2、可以通過動畫事務(CATransaction)關閉默認的隱式動畫效果。

    [CATransaction begin];[CATransaction setDisableActions:YES];self.myLayer.position = CGPointMake(10, 10);[CATransaction commit];

6、繪圖層 position 和 anchorPoint 屬性

  • position 和 anchorPoint 屬性都是 CGPoint 類型的。

    position :位置,可以用來設置 CALayer 在父層中的位置,它是以父層的左上角為坐標原點(0, 0)。anchorPoint :錨點,稱為 "定位點",它決定著 CALayer 身上的哪個點會在 position 屬性所指的位置。它的 x、y 取值范圍都是 0~1,默認值為 (0.5, 0.5)。
  • 1、anchorPoint 為默認值(0.5, 0.5)

    CALayer *myLayer = [CALayer layer];myLayer.backgroundColor = [UIColor redColor].CGColor;myLayer.bounds = CGRectMake(0, 0, 100, 100);// 設置層的位置myLayer.position = CGPointMake(100, 100);[self.view.layer addSublayer:myLayer];
    • 設置了 myLayer 的 position 為(100, 100),又因為 anchorPoint 默認是(0.5, 0.5),所以最后的效果是 myLayer 的中點會在父層的(100, 100)位置。

  • 2、anchorPoint 為(0, 0)

    • 若將 anchorPoint 改為(0, 0),myLayer 的左上角會在(100, 100)位置。

      myLayer.anchorPoint = CGPointMake(0, 0);

  • 3、anchorPoint 為(1, 1)

    • 若將 anchorPoint 改為(1, 1),myLayer 的右下角會在(100, 100)位置。

      myLayer.anchorPoint = CGPointMake(1, 1);

  • 4、anchorPoint 為(0, 1)

    • 將 anchorPoint 改為(0, 1),myLayer 的左下角會在(100, 100)位置。

      myLayer.anchorPoint = CGPointMake(0, 1);

7、自定義繪圖層

7.1 自定義繪圖層方法 1

  • 創建一個 CALayer 的子類,然后覆蓋 drawInContext: 方法,使用 Quartz2D API 進行繪圖。

  • QCLayer.h

    @interface QCLayer : CALayer@end
  • QCLayer.m

    @implementation QCLayer#pragma mark 繪制一個實心三角形- (void)drawInContext:(CGContextRef)ctx {// 設置為藍色CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);// 設置起點CGContextMoveToPoint(ctx, 50, 0);// 從 (50, 0) 連線到 (0, 100)CGContextAddLineToPoint(ctx, 0, 100);// 從 (0, 100) 連線到 (100, 100)CGContextAddLineToPoint(ctx, 100, 100);// 合并路徑,連接起點和終點CGContextClosePath(ctx);// 繪制路徑CGContextFillPath(ctx);}@end
  • ViewController.m

    QCLayer *layer = [QCLayer layer];// 設置層的寬高layer.bounds = CGRectMake(0, 0, 100, 100);// 設置層的位置layer.position = CGPointMake(100, 100);// 開始繪制圖層,需要調用這個方法,才會觸發 drawInContext: 方法的調用,然后進行繪圖[layer setNeedsDisplay];[self.view.layer addSublayer:layer];
  • 效果

7.2 自定義繪圖層方法 2

  • 設置 CALayer 的 delegate,然后讓 delegate 實現 drawLayer:inContext: 方法,當 CALayer 需要繪圖時,會調用 delegate 的 drawLayer:inContext: 方法進行繪圖。
  • 這里要注意的是:不能再將某個 UIView 設置為 CALayer 的 delegate,因為 UIView 對象已經是它內部根層的 delegate,再次設置為其他層的 delegate 就會出問題。UIView 和它內部 CALayer 的默認關系圖:

  • 創建新的層,設置 delegate,然后添加到控制器的 view 的 layer 中。

    CALayer *layer = [CALayer layer];// 設置 delegate,這里的 self 是指控制器layer.delegate = self;// 設置層的寬高layer.bounds = CGRectMake(0, 0, 100, 100);// 設置層的位置layer.position = CGPointMake(100, 100);// 開始繪制圖層,需要調用這個方法,才會通知 delegate 進行繪圖[layer setNeedsDisplay];[self.view.layer addSublayer:layer];
  • 讓 CALayer 的 delegate(前面設置的是控制器)實現 drawLayer:inContext: 方法

    #pragma mark 畫一個矩形框- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {// 設置藍色CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);// 設置邊框寬度CGContextSetLineWidth(ctx, 10);// 添加一個跟層一樣大的矩形到路徑中CGContextAddRect(ctx, layer.bounds);// 繪制路徑CGContextStrokePath(ctx);}
  • 效果

7.3 UIView 的詳細顯示過程

  • 當 UIView 需要顯示時,它內部的層會準備好一個 CGContextRef(圖形上下文),然后調用 delegate(這里就是 UIView)的 drawLayer:inContext: 方法,并且傳入已經準備好的 CGContextRef 對象。而 UIView 在 drawLayer:inContext: 方法中又會調用自己的 drawRect: 方法

  • 平時在 drawRect: 中通過 UIGraphicsGetCurrentContext() 獲取的就是由層傳入的 CGContextRef 對象,在 drawRect: 中完成的所有繪圖都會填入層的 CGContextRef 中,然后被拷貝至屏幕。

8、漸變圖層

  • 漸變圖層 CAGradientLayer : CALayer

  • 添加漸變圖層

    CAGradientLayer *gradientLayer = [CAGradientLayer layer];gradientLayer.frame = self.imageView.bounds;// 設置透明度gradientLayer.opacity = 0.5;// 設置漸變顏色gradientLayer.colors = @[(id)[UIColor clearColor].CGColor, (id)[UIColor blackColor].CGColor];[self.imageView.layer addSublayer:gradientLayer]; CAGradientLayer *gradientLayer = [CAGradientLayer layer];gradientLayer.frame = self.imageView.bounds;// 設置透明度gradientLayer.opacity = 0.5;// 設置漸變顏色gradientLayer.colors = @[(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor yellowColor].CGColor];// 設置漸變定位點gradientLayer.locations = @[@0.1, @0.4, @0.8];// 設置漸變開始點,取值 0~1gradientLayer.startPoint = CGPointMake(0, 1);[self.imageView.layer addSublayer:gradientLayer];
    • 效果

9、復制圖層

  • 復制圖層 CAReplicatorLayer : CALayer,可以把圖層里面所有子層復制

  • 添加復制圖層

    CAReplicatorLayer *repLayer = [CAReplicatorLayer layer];repLayer.frame = self.view.bounds;[self.view.layer addSublayer:repLayer];// 添加子層[repLayer addSublayer:self.imageView.layer];// 設置有多少個子層,包括原始層repLayer.instanceCount = 4;// 設置子層偏移量,不包括原始層,相對于原始層 x 偏移repLayer.instanceTransform = CATransform3DMakeTranslation(70, 0, 0);// 設置子層背景色repLayer.instanceColor = [UIColor greenColor].CGColor;// 設置子層陰影repLayer.instanceAlphaOffset = -0.1;repLayer.instanceRedOffset = -0.1;repLayer.instanceGreenOffset = -0.1;repLayer.instanceBlueOffset = -0.1;// 設置子層動畫延遲時間,子層有動畫時有效repLayer.instanceDelay = 0; CAReplicatorLayer *repLayer = [CAReplicatorLayer layer];repLayer.frame = self.view.bounds;[self.view.layer addSublayer:repLayer];// 添加子層CALayer *layer = [CALayer layer];layer.anchorPoint = CGPointMake(0.5, 1);layer.position = CGPointMake(100, 300);layer.bounds = CGRectMake(0, 0, 30, 150);layer.backgroundColor = [UIColor whiteColor].CGColor;[repLayer addSublayer:layer];// 添加子層動畫CABasicAnimation *anim = [CABasicAnimation animation];anim.keyPath = @"transform.scale.y";anim.toValue = @0.1;anim.duration = 0.5;anim.repeatCount = MAXFLOAT;anim.autoreverses = YES;[layer addAnimation:anim forKey:nil];// 設置子層repLayer.instanceCount = 4;repLayer.instanceTransform = CATransform3DMakeTranslation(45, 0, 0);repLayer.instanceDelay = 0.1;repLayer.instanceColor = [UIColor greenColor].CGColor;repLayer.instanceGreenOffset = -0.3;
    • 效果

轉載于:https://www.cnblogs.com/QianChia/p/6348043.html

總結

以上是生活随笔為你收集整理的iOS - CALayer 绘图层的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产亚洲精品成人无码精品网站 | 在线观看av一区 | 国产性猛交xxxⅹ交酡全过程 | 亚洲aⅴ在线| 久久免费看视频 | 自拍偷拍亚洲视频 | 国产精品成人免费精品自在线观看 | 1024手机看片日韩 | 日本天堂在线观看 | 少妇户外露出[11p] | 精品人人妻人人澡人人爽牛牛 | 久久精品在线观看 | 伊人久久免费视频 | 天堂av免费在线观看 | 欧美在线视频你懂的 | 国产一区二区在线观看视频 | 精品天堂 | 丰满少妇一区二区 | 777奇米色 | 国产精品久久久久久无人区 | 美女啪啪免费视频 | 91精品中文字幕 | 尤物网站在线观看 | 自拍视频网址 | 日韩av一卡二卡 | 欧美性做爰大片免费 | 亚洲少妇视频 | 亚洲青色在线 | 成人娱乐网 | 综合色88| 又嫩又硬又黄又爽的视频 | 亚洲AV无码乱码国产精品色欲 | 免费草逼视频 | 免费精品国产 | 国产最新毛片 | 欧美亚洲在线观看 | 国产黄av| 中文字幕av无码一区二区三区 | 欧美在线中文 | 热久久最新网址 | 欧美日韩中文国产 | 成人久久一区 | 亚洲高清毛片一区二区 | 九色九一| 国产福利免费看 | 小少妇哺乳喂奶播放 | 夜夜涩| 国产精品视频成人 | 秋霞网一区二区三区 | www.av72| 天堂网中文 | 亚洲黄色第一页 | 久久久精品蜜桃 | 国产精品久久久久久久久岛 | 免费色网址 | 国精产品乱码一区一区三区四区 | 五月天婷婷综合 | а 天堂 在线 | 韩国成人在线视频 | 免费观看成人鲁鲁鲁鲁鲁视频 | 爱看av在线 | 手机av在线免费观看 | 欧美日韩国产图片 | 精品一区二区电影 | 黑人巨大精品欧美黑寡妇 | 亚洲午夜在线视频 | 国产自偷自拍视频 | 亚洲一区二区三区人妻 | 久久久久人妻一区精品 | 麻豆网站在线免费观看 | 最新av在线网址 | 深爱五月激情网 | 伊人av一区| 玉蒲团在线 | 亚洲欧美中文字幕5发布 | 国产精品日韩一区 | 欧美精品video | 久热只有精品 | 日本乱码视频 | 国产亚洲精品码 | 国产黄色片在线观看 | 福利小视频在线播放 | 武侠古典av | 中文字幕一区二区三区精品 | a视频免费 | 久久免费av | 18禁裸乳无遮挡啪啪无码免费 | 在线免费观看欧美大片 | 国产又黄又粗又硬 | 奶水旺盛的少妇在线播放 | 亚洲永久免费视频 | 欧美一级免费大片 | 高清欧美性猛交xxxx | 亚洲国产精品99久久 | 国色天香av| 国产伦精品一区二区三区照片 | 人人玩人人弄 | 一二级毛片 | 一级片在线免费 |