CALayer 知識:建立帶陰影製作效果的圓角圖片圖層和建立自訂繪畫內容圖層,
效果如下:
KMLayerDelegate.h
1 #import <UIKit/UIKit.h>2 3 @interface KMLayerDelegate : NSObject4 5 @end
KMLayerDelegate.m
1 #import "KMLayerDelegate.h" 2 3 @implementation KMLayerDelegate 4 5 /** 6 * 根據角度,擷取對應的弧度 7 * 8 * @param degree 角度 9 *10 * @return 對應的弧度11 */12 static inline double radian(double degree) {13 return degree * M_PI/180;14 }15 16 /**17 * 繪畫著色模式內容;繪畫預定寬高大小的儲存格,每個儲存格包含兩個半圓,分別為『左上方的上半圓』和『右下邊的下半圓』18 *19 * @param info 資訊20 * @param context 上下文21 */22 void drawColoredPattern(void *info, CGContextRef context) {23 CGColorRef dotColor = [UIColor colorWithHue:0.0 saturation:0.0 brightness:0.0 alpha:0.8].CGColor; //圓點顏色;以色彩、飽和度、亮度和不透明度組合的顏色24 CGColorRef dotShadowColor = [UIColor orangeColor].CGColor; //圓點陰影顏色25 26 CGContextSetFillColorWithColor(context, dotColor); //設定填充色27 CGContextSetShadowWithColor(context, CGSizeMake(2.0, 2.0), 1, dotShadowColor); //設定陰影顏色;以陰影位置偏差為(2.0, 2.0)、模糊效果的 dotShadowColor 作為陰影顏色28 29 CGContextAddArc(context, 10.0, 10.0, 10.0, 0.0, radian(180.0), 1); //添加圓點;以置中點為(10.0, 10.0)、半徑為10.0、順時針畫0.0到180.0弧度的圓點(即為上半圓),注意0.0弧度為水平線左邊位置開始30 CGContextFillPath(context);31 32 CGContextAddArc(context, 30.0, 20.0, 10.0, 0.0, radian(180.0), 0); //添加圓點;以置中點為(30.0, 20.0)、半徑為10.0、逆時針畫0.0到180.0弧度的圓點(即為下半圓),注意0.0弧度為水平線左邊位置開始33 CGContextFillPath(context);34 }35 36 /**37 * 繪畫內容圖層38 *39 * @param layer 當前圖層40 * @param context 上下文41 */42 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context {43 //圖層背景顏色44 CGColorRef backgroundColor = [UIColor lightGrayColor].CGColor;45 CGContextSetFillColorWithColor(context, backgroundColor);46 CGContextFillRect(context, layer.bounds);47 48 static const CGPatternCallbacks callbacks = { 0, &drawColoredPattern, NULL };49 //繪畫連續的儲存格,每個儲存格的內容由 drawColoredPattern 方法決定50 CGContextSaveGState(context);51 CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);52 CGContextSetFillColorSpace(context, patternSpace);53 CGColorSpaceRelease(patternSpace);54 55 CGPatternRef pattern = CGPatternCreate(NULL,56 layer.bounds,57 CGAffineTransformIdentity,58 40.0, //儲存格的寬度59 40.0, //儲存格的高度60 kCGPatternTilingConstantSpacing,61 true,62 &callbacks);63 CGFloat alpha = 1.0; //著色模式內容的不透明度64 CGContextSetFillPattern(context, pattern, &alpha);65 CGPatternRelease(pattern);66 CGContextFillRect(context, layer.bounds);67 CGContextRestoreGState(context);68 }69 70 @end
ViewController.h
1 #import <UIKit/UIKit.h>2 #import "KMLayerDelegate.h"3 4 @interface ViewController : UIViewController5 @property (strong, nonatomic) KMLayerDelegate *layerDelegate;6 7 @end
ViewController.m
1 #import "ViewController.h" 2 3 static const CGFloat cornerRadius = 10.0; 4 @interface ViewController () 5 - (void)createShadowCornerImage:(UIImage *)image withRootLayer:(CALayer *)rootLayer; 6 - (void)createCustomDrawingLayer:(CALayer *)rootLayer; 7 - (void)layoutUI; 8 @end 9 10 @implementation ViewController11 12 - (void)viewDidLoad {13 [super viewDidLoad];14 15 [self layoutUI];16 }17 18 - (void)didReceiveMemoryWarning {19 [super didReceiveMemoryWarning];20 // Dispose of any resources that can be recreated.21 }22 23 /**24 * 建立帶陰影製作效果的圓角圖片圖層25 *26 * @param image 圖片27 * @param rootLayer 根圖層28 */29 - (void)createShadowCornerImage:(UIImage *)image withRootLayer:(CALayer *)rootLayer {30 //子圖層(圖片的陰影圖層)31 CALayer *subLayer = [CALayer layer];32 subLayer.frame = CGRectMake(40.0, 40.0, 240.0, 240.0);33 subLayer.backgroundColor = [UIColor lightGrayColor].CGColor;34 subLayer.cornerRadius = cornerRadius;35 subLayer.borderColor = [UIColor blackColor].CGColor;36 subLayer.borderWidth = 2.0;37 subLayer.shadowColor = [UIColor blackColor].CGColor; //設定陰影顏色38 subLayer.shadowOpacity = 0.7; //設定陰影不透明度39 subLayer.shadowOffset = CGSizeMake(4.0, 3.0); //設定陰影位置偏差40 subLayer.shadowRadius = 5.0; //設定陰影圓角半徑41 [rootLayer addSublayer:subLayer];42 43 //子圖層的子圖層(圖片的內容圖層)44 CALayer *imageLayer = [CALayer layer];45 imageLayer.frame = subLayer.bounds;46 imageLayer.contents = (id)image.CGImage;47 imageLayer.masksToBounds = YES; //設定標示剪下界限;內容圖層需設定為 YES,才能有圓角效果48 imageLayer.cornerRadius = cornerRadius;49 CGAffineTransform affineTransform = CGAffineTransformConcat(CGAffineTransformMakeScale(0.8, 0.8), CGAffineTransformMakeRotation(M_PI_4/9)); //合并縮放和旋轉效果;以0.8比例置中縮放,以45度/9=5度的角度順時針旋轉50 imageLayer.affineTransform = affineTransform;51 [subLayer addSublayer:imageLayer];52 }53 54 /**55 * 建立自訂繪畫內容圖層56 *57 * @param rootLayer 根圖層58 */59 - (void)createCustomDrawingLayer:(CALayer *)rootLayer {60 CALayer *drawingLayer = [CALayer layer];61 drawingLayer.frame = CGRectMake(40.0, 320.0, 240.0, 240.0);62 drawingLayer.backgroundColor = [UIColor orangeColor].CGColor; //背景顏色會被內容圖層遮住,所以最終呈現的以內容圖層為準63 drawingLayer.masksToBounds = YES; //設定標示剪下界限;內容圖層需設定為 YES,才能有圓角效果64 drawingLayer.cornerRadius = cornerRadius;65 drawingLayer.borderColor = [UIColor blackColor].CGColor;66 drawingLayer.borderWidth = 2.0;67 drawingLayer.shadowColor = [UIColor darkGrayColor].CGColor; //設定陰影顏色68 drawingLayer.shadowOpacity = 0.8; //設定陰影不透明度69 drawingLayer.shadowOffset = CGSizeMake(8.0, 6.0); //設定陰影位置偏差70 drawingLayer.shadowRadius = 5.0; //設定陰影圓角半徑71 72 _layerDelegate = [KMLayerDelegate new];73 drawingLayer.delegate = _layerDelegate;74 [drawingLayer setNeedsDisplay]; //這裡必須調用方法 setNeedsDisplay,才會觸發委託代理方法 drawLayer:75 [rootLayer addSublayer:drawingLayer];76 }77 78 - (void)layoutUI {79 //根圖層80 CALayer *rootLayer = self.view.layer;81 rootLayer.backgroundColor = [UIColor cyanColor].CGColor;82 rootLayer.cornerRadius = 40.0;83 84 [self createShadowCornerImage:[UIImage imageNamed:@"Emoticon_tusiji_icon2"]85 withRootLayer:rootLayer];86 [self createCustomDrawingLayer:rootLayer];87 }88 89 @end