• CALayer 知识:创建带阴影效果的圆角图片图层和创建自定义绘画内容图层


    效果如下:

    KMLayerDelegate.h

    1 #import <UIKit/UIKit.h>
    2 
    3 @interface KMLayerDelegate : NSObject
    4 
    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 <QuartzCore/CALayer.h>
    3 #import "KMLayerDelegate.h"
    4 
    5 @interface ViewController : UIViewController
    6 @property (strong, nonatomic) KMLayerDelegate *layerDelegate;
    7 
    8 @end

    ViewController.m

      1 #import "ViewController.h"
      2 
      3 static CGFloat const kCornerRadius = 10.0;
      4 static CGFloat const kWidthOfIcon = 120.0;
      5 static CGFloat const kLineWidth = 5.0;
      6 static CGFloat const kBaseNumber = 24; ///< 24等分法
      7 
      8 @interface ViewController ()
      9 - (void)createShadowCornerImage:(UIImage *)image withRootLayer:(CALayer *)rootLayer;
     10 - (void)createCustomDrawingLayer:(CALayer *)rootLayer;
     11 - (void)createSuccessIconDrawingLayer:(CALayer *)rootLayer;
     12 - (void)createWarningIconDrawingLayer:(CALayer *)rootLayer;
     13 - (void)createErrorIconDrawingLayer:(CALayer *)rootLayer;
     14 - (void)layoutUI;
     15 @end
     16 
     17 @implementation ViewController
     18 
     19 - (void)viewDidLoad {
     20     [super viewDidLoad];
     21     
     22     [self layoutUI];
     23 }
     24 
     25 - (void)didReceiveMemoryWarning {
     26     [super didReceiveMemoryWarning];
     27     // Dispose of any resources that can be recreated.
     28 }
     29 
     30 /**
     31  *  创建带阴影效果的圆角图片图层
     32  *
     33  *  @param image     图片
     34  *  @param rootLayer 根图层
     35  */
     36 - (void)createShadowCornerImage:(UIImage *)image withRootLayer:(CALayer *)rootLayer {
     37     // 子图层(图片的阴影图层)
     38     CALayer *subLayer = [CALayer layer];
     39     subLayer.frame = CGRectMake(20.0, 40.0, 150.0, 150.0);
     40     subLayer.backgroundColor = [UIColor lightGrayColor].CGColor;
     41     subLayer.cornerRadius = kCornerRadius;
     42     subLayer.borderColor = [UIColor blackColor].CGColor;
     43     subLayer.borderWidth = 2.0;
     44     subLayer.shadowColor = [UIColor blackColor].CGColor; // 设置阴影颜色
     45     subLayer.shadowOpacity = 0.7; // 设置阴影不透明度
     46     subLayer.shadowOffset = CGSizeMake(4.0, 3.0); // 设置阴影位置偏差
     47     subLayer.shadowRadius = 5.0; // 设置阴影圆角半径
     48     [rootLayer addSublayer:subLayer];
     49     
     50     // 子图层的子图层(图片的内容图层)
     51     CALayer *imageLayer = [CALayer layer];
     52     imageLayer.frame = subLayer.bounds;
     53     imageLayer.contents = (id)image.CGImage;
     54     imageLayer.masksToBounds = YES; // 设置标示剪切界限;内容图层需设置为 YES,才能有圆角效果
     55     imageLayer.cornerRadius = kCornerRadius;
     56     CGAffineTransform affineTransform = CGAffineTransformConcat(CGAffineTransformMakeScale(0.8, 0.8), CGAffineTransformMakeRotation(M_PI_4/9)); // 合并缩放和旋转效果;以0.8比例居中缩放,以45度/9=5度的角度顺时针旋转
     57     imageLayer.affineTransform = affineTransform;
     58     [subLayer addSublayer:imageLayer];
     59 }
     60 
     61 /**
     62  *  创建自定义绘画内容图层(KMLayerDelegate)
     63  *
     64  *  @param rootLayer 根图层
     65  */
     66 - (void)createCustomDrawingLayer:(CALayer *)rootLayer {
     67     CALayer *drawingLayer = [CALayer layer];
     68     drawingLayer.frame = CGRectMake(200.0, 40.0, 150.0, 150.0);
     69     drawingLayer.backgroundColor = [UIColor orangeColor].CGColor; // 背景颜色会被内容图层遮住,所以最终呈现的以内容图层为准
     70     drawingLayer.masksToBounds = YES; // 设置标示剪切界限;内容图层需设置为 YES,才能有圆角效果
     71     drawingLayer.cornerRadius = kCornerRadius;
     72     drawingLayer.borderColor = [UIColor blackColor].CGColor;
     73     drawingLayer.borderWidth = 2.0;
     74     drawingLayer.shadowColor = [UIColor darkGrayColor].CGColor; // 设置阴影颜色
     75     drawingLayer.shadowOpacity = 0.8; // 设置阴影不透明度
     76     drawingLayer.shadowOffset = CGSizeMake(8.0, 6.0); // 设置阴影位置偏差
     77     drawingLayer.shadowRadius = 5.0; // 设置阴影圆角半径
     78     
     79     _layerDelegate = [KMLayerDelegate new];
     80     drawingLayer.delegate = _layerDelegate;
     81     [drawingLayer setNeedsDisplay]; // 这里必须调用方法 setNeedsDisplay,才会触发委托代理方法 drawLayer:
     82     [rootLayer addSublayer:drawingLayer];
     83 }
     84 
     85 /**
     86  *  创建绿色成功图标内容图层
     87  *
     88  *  @param rootLayer 根图层
     89  */
     90 - (void)createSuccessIconDrawingLayer:(CALayer *)rootLayer {
     91     // 成功图标颜色:绿色
     92     UIColor *const color = [UIColor colorWithRed:0.000 green:1.000 blue:0.502 alpha:1.000];
     93     
     94     // 贝塞尔曲线路径;开始画圆
     95     UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0.0, 0.0, kWidthOfIcon, kWidthOfIcon)];
     96     // 然后以三点形成「打勾」效果
     97     [path moveToPoint:CGPointMake(kWidthOfIcon/kBaseNumber*4, kWidthOfIcon/kBaseNumber*12)];
     98     CGPoint p1 = CGPointMake(kWidthOfIcon/kBaseNumber*8, kWidthOfIcon/kBaseNumber*16);
     99     [path addLineToPoint:p1];
    100     
    101     CGPoint p2 = CGPointMake(kWidthOfIcon/kBaseNumber*18, kWidthOfIcon/kBaseNumber*6);
    102     [path addLineToPoint:p2];
    103     
    104     // 子图层
    105     CAShapeLayer *subLayer = [CAShapeLayer layer];
    106     subLayer.frame = CGRectMake(125.0, 210.0, kWidthOfIcon, kWidthOfIcon);
    107     subLayer.path = path.CGPath;
    108     subLayer.lineWidth = kLineWidth; // 线条宽度
    109     subLayer.strokeColor = color.CGColor; // 线条颜色
    110     subLayer.fillColor = [UIColor clearColor].CGColor; //清除填充色
    111     [rootLayer addSublayer:subLayer];
    112 }
    113 
    114 /**
    115  *  创建黄色警告图标内容图层
    116  *
    117  *  @param rootLayer 根图层
    118  */
    119 - (void)createWarningIconDrawingLayer:(CALayer *)rootLayer {
    120     CGFloat centerOfWidth = (kWidthOfIcon - kLineWidth)/2;
    121     // 警告图标颜色:黄色
    122     UIColor *const color = [UIColor colorWithRed:1.000 green:0.800 blue:0.400 alpha:1.000];
    123     
    124     // 贝塞尔曲线路径;开始画圆
    125     UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0.0, 0.0, kWidthOfIcon, kWidthOfIcon)];
    126     // 然后画感叹号
    127     [path moveToPoint:CGPointMake(centerOfWidth, kWidthOfIcon/kBaseNumber*4)];
    128     CGPoint p1 = CGPointMake(centerOfWidth, kWidthOfIcon/kBaseNumber*16);
    129     [path addLineToPoint:p1];
    130     
    131     [path moveToPoint:CGPointMake(centerOfWidth, kWidthOfIcon/kBaseNumber*19)];
    132     [path addArcWithCenter:CGPointMake(centerOfWidth, kWidthOfIcon/kBaseNumber*19) radius:3.0 startAngle:0 endAngle:M_PI*2 clockwise:YES];
    133     
    134     // 子图层
    135     CAShapeLayer *subLayer = [CAShapeLayer layer];
    136     subLayer.frame = CGRectMake(125.0, 360.0, kWidthOfIcon, kWidthOfIcon);
    137     subLayer.path = path.CGPath;
    138     subLayer.lineWidth = kLineWidth; // 线条宽度
    139     subLayer.strokeColor = color.CGColor; // 线条颜色
    140     subLayer.fillColor = [UIColor clearColor].CGColor; //清除填充色
    141     [rootLayer addSublayer:subLayer];
    142 }
    143 
    144 /**
    145  *  创建红色错误图标内容图层
    146  *
    147  *  @param rootLayer 根图层
    148  */
    149 - (void)createErrorIconDrawingLayer:(CALayer *)rootLayer {
    150     CGFloat keyVal1 = kWidthOfIcon/kBaseNumber*6;
    151     CGFloat keyVal2 = kWidthOfIcon/kBaseNumber*18;
    152     // 失败图标颜色:红色
    153     UIColor *const color = [UIColor colorWithRed:1.000 green:0.400 blue:0.400 alpha:1.000];
    154     
    155     // 贝塞尔曲线路径;开始画圆
    156     UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0.0, 0.0, kWidthOfIcon, kWidthOfIcon)];
    157     // 然后画交叉号
    158     CGPoint p1 =  CGPointMake(keyVal1, keyVal1);
    159     [path moveToPoint:p1];
    160     
    161     CGPoint p2 =  CGPointMake(keyVal2, keyVal2);
    162     [path addLineToPoint:p2];
    163     
    164     CGPoint p3 =  CGPointMake(keyVal2, keyVal1);
    165     [path moveToPoint:p3];
    166     
    167     CGPoint p4 =  CGPointMake(keyVal1, keyVal2);
    168     [path addLineToPoint:p4];
    169     
    170     // 子图层
    171     CAShapeLayer *subLayer = [CAShapeLayer layer];
    172     subLayer.frame = CGRectMake(125.0, 510.0, kWidthOfIcon, kWidthOfIcon);
    173     subLayer.path = path.CGPath;
    174     subLayer.lineWidth = kLineWidth; // 线条宽度
    175     subLayer.strokeColor = color.CGColor; // 线条颜色
    176     subLayer.fillColor = [UIColor clearColor].CGColor; //清除填充色
    177     [rootLayer addSublayer:subLayer];
    178 }
    179 
    180 - (void)layoutUI {
    181     //根图层
    182     CALayer *rootLayer = self.view.layer;
    183     rootLayer.backgroundColor = [UIColor colorWithRed:0.769 green:0.940 blue:0.943 alpha:1.000].CGColor;
    184     rootLayer.cornerRadius = 40.0;
    185     
    186     [self createShadowCornerImage:[UIImage imageNamed:@"Emoticon_tusiji_icon2"]
    187                     withRootLayer:rootLayer];
    188     [self createCustomDrawingLayer:rootLayer];
    189     [self createSuccessIconDrawingLayer:rootLayer];
    190     [self createWarningIconDrawingLayer:rootLayer];
    191     [self createErrorIconDrawingLayer:rootLayer];
    192 }
    193 
    194 @end
  • 相关阅读:
    循环链表结构
    复杂的权衡之时间、空间和单链表结构
    单链表操作之删除
    单链表操作之插入
    单链表操作之替换
    单链表操作之搜索
    文件系统的原理
    类加载的三种方式比较
    shell中awk printf的用法
    推荐网站
  • 原文地址:https://www.cnblogs.com/huangjianwu/p/4679026.html
Copyright © 2020-2023  润新知