IOS Core Animation Advanced Techniques的学习笔记(三)

第四章:Visual Effects

 

Rounded Corners

 

例子4.1 cornerRadius

 

源码在这里下载:http://www.informit.com/title/9780133440751

 

  1. #import "ViewController.h"  
  2. #import <QuartzCore/QuartzCore.h>  
  3.   
  4. @interface ViewController ()  
  5.   
  6. @property (nonatomic, weak) IBOutlet UIView *layerView1;  
  7. @property (nonatomic, weak) IBOutlet UIView *layerView2;  
  8.   
  9. @end  
  10.   
  11. @implementation ViewController  
  12.   
  13. - (void)viewDidLoad  
  14. {  
  15.     [super viewDidLoad];  
  16.       
  17.     //set the corner radius on our layers  
  18.     self.layerView1.layer.cornerRadius = 20.0f;  
  19.     self.layerView2.layer.cornerRadius = 20.0f;  
  20.       
  21.     //enable clipping on the second layer  
  22.     self.layerView2.layer.masksToBounds = YES;  
  23. }  
  24.   
  25. @end  

 

稍微修改一下

 

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //set the corner radius on our layers  
  6.     self.layerView1.layer.cornerRadius = 20.0f;  
  7.     self.layerView2.layer.cornerRadius = 20.0f;  
  8.   
  9.     self.layerView1.clipsToBounds = YES;  
  10.   
  11.     //enable clipping on the second layer  
  12.     self.layerView2.layer.masksToBounds = YES;  
  13. }  


前面讲过了,UIView的clipsToBounds的函数等同于masksToBounds


Layer Borders

例子4.2 borderWidth

 

 

  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *layerView1;  
  4. @property (nonatomic, weak) IBOutlet UIView *layerView2;  
  5.   
  6. @end  
  7.   
  8. @implementation ViewController  
  9.   
  10. - (void)viewDidLoad  
  11. {  
  12.     [super viewDidLoad];  
  13.       
  14.     //set the corner radius on our layers  
  15.     self.layerView1.layer.cornerRadius = 20.0f;  
  16.     self.layerView2.layer.cornerRadius = 20.0f;  
  17.       
  18.     //add a border to our layers  
  19.     self.layerView1.layer.borderWidth = 5.0f;  
  20.     self.layerView2.layer.borderWidth = 5.0f;  
  21.       
  22.     //enable clipping on the second layer  
  23.     self.layerView2.layer.masksToBounds = YES;  
  24. }  
  25.   
  26. @end  



修改代码 borderColor

 

 

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //set the corner radius on our layers  
  6.     self.layerView1.layer.cornerRadius = 20.0f;  
  7.     self.layerView2.layer.cornerRadius = 20.0f;  
  8.       
  9.     //add a border to our layers  
  10.     self.layerView1.layer.borderWidth = 5.0f;  
  11.     self.layerView1.layer.borderColor = [UIColor brownColor].CGColor;  
  12.     self.layerView2.layer.borderWidth = 5.0f;  
  13.       
  14.     //enable clipping on the second layer  
  15.     self.layerView2.layer.masksToBounds = YES;  
  16. }  



再做个试验,修改代码

 



  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //set the corner radius on our layers  
  6.     //self.layerView1.layer.cornerRadius = 20.0f;  
  7.     self.layerView2.layer.cornerRadius = 20.0f;  
  8.       
  9.     //add a border to our layers  
  10.     self.layerView1.layer.borderWidth = 5.0f;  
  11.     self.layerView1.layer.borderColor = [UIColor brownColor].CGColor;  
  12.     self.layerView2.layer.borderWidth = 5.0f;  
  13.       
  14.     //enable clipping on the second layer  
  15.     self.layerView2.layer.masksToBounds = YES;  
  16. }  


没有看到红色

 

再修改

看结果

验证borderWidth是往内部画的,和使用CGContextStrokeEllipseInRect画圆时的方式不同

 

Drop Shadows & Shadow Clipping

先修改例子2.2

 

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //load an image  
  6.     UIImage *image = [UIImage imageNamed:@"Snowman.png"];  
  7.   
  8.     self.layerView.backgroundColor = [UIColor clearColor];  
  9.   
  10.     //add it directly to our view's layer  
  11.     self.layerView.layer.contents = (__bridge id)image.CGImage;  
  12.       
  13.     //center the image  
  14.     self.layerView.layer.contentsGravity = kCAGravityCenter;  
  15.       
  16.     //set the contentsScale to match screen  
  17.     self.layerView.layer.contentsScale = image.scale;  
  18.   
  19.     self.layerView.layer.shadowOpacity = 0.3;  
  20.     self.layerView.layer.shadowOffset = CGSizeMake(10, 20);  
  21.   
  22.     //clip the snowman to fit his bounds  
  23.     //self.layerView.layer.masksToBounds = YES;  
  24. }  

 

继续

 

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //load an image  
  6.     UIImage *image = [UIImage imageNamed:@"Snowman.png"];  
  7.   
  8.     //self.layerView.backgroundColor = [UIColor clearColor];  
  9.   
  10.     //add it directly to our view's layer  
  11.     self.layerView.layer.contents = (__bridge id)image.CGImage;  
  12.       
  13.     //center the image  
  14.     self.layerView.layer.contentsGravity = kCAGravityCenter;  
  15.       
  16.     //set the contentsScale to match screen  
  17.     self.layerView.layer.contentsScale = image.scale;  
  18.   
  19.     self.layerView.layer.shadowOpacity = 0.3;  
  20.     self.layerView.layer.shadowOffset = CGSizeMake(10, 20);  
  21.   
  22.     //clip the snowman to fit his bounds  
  23.     //self.layerView.layer.masksToBounds = YES;  
  24. }  

 

再改

 

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //load an image  
  6.     UIImage *image = [UIImage imageNamed:@"Snowman.png"];  
  7.   
  8.     self.layerView.backgroundColor = [UIColor clearColor];  
  9.   
  10.     //add it directly to our view's layer  
  11.     self.layerView.layer.contents = (__bridge id)image.CGImage;  
  12.       
  13.     //center the image  
  14.     self.layerView.layer.contentsGravity = kCAGravityCenter;  
  15.       
  16.     //set the contentsScale to match screen  
  17.     self.layerView.layer.contentsScale = image.scale;  
  18.   
  19.     self.layerView.layer.shadowOpacity = 0.3;  
  20.     self.layerView.layer.shadowOffset = CGSizeMake(10, 20);  
  21.   
  22.     //clip the snowman to fit his bounds  
  23.     self.layerView.layer.masksToBounds = YES;  
  24. }  



再改

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //load an image  
  6.     UIImage *image = [UIImage imageNamed:@"Snowman.png"];  
  7.   
  8.     //self.layerView.backgroundColor = [UIColor clearColor];  
  9.   
  10.     //add it directly to our view's layer  
  11.     self.layerView.layer.contents = (__bridge id)image.CGImage;  
  12.       
  13.     //center the image  
  14.     self.layerView.layer.contentsGravity = kCAGravityCenter;  
  15.       
  16.     //set the contentsScale to match screen  
  17.     self.layerView.layer.contentsScale = image.scale;  
  18.   
  19.     self.layerView.layer.shadowOpacity = 0.3;  
  20.     self.layerView.layer.shadowOffset = CGSizeMake(10, 20);  
  21.   
  22.     //clip the snowman to fit his bounds  
  23.     self.layerView.layer.masksToBounds = YES;  
  24. }  

shadow是根据layer实际显示的内容绘制的

再看看例子4.3去体会一下

 

源码在这里下载:http://www.informit.com/title/9780133440751

 

 

 

The shadowPath Property

 

例子4.4

 

  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *layerView1;  
  4. @property (nonatomic, weak) IBOutlet UIView *layerView2;  
  5.   
  6. @end  
  7.   
  8. @implementation ViewController  
  9.   
  10. - (void)viewDidLoad  
  11. {  
  12.     [super viewDidLoad];  
  13.       
  14.     //enable layer shadows  
  15.     self.layerView1.layer.shadowOpacity = 0.5f;  
  16.     self.layerView2.layer.shadowOpacity = 0.5f;  
  17.       
  18.     //create a square shadow  
  19.     CGMutablePathRef squarePath = CGPathCreateMutable();  
  20.     CGPathAddRect(squarePath, NULL, self.layerView1.bounds);  
  21.     self.layerView1.layer.shadowPath = squarePath;  
  22.     CGPathRelease(squarePath);  
  23.       
  24.     //create a circular shadow  
  25.     CGMutablePathRef circlePath = CGPathCreateMutable();  
  26.     CGPathAddEllipseInRect(circlePath, NULL, self.layerView2.bounds);  
  27.     self.layerView2.layer.shadowPath = circlePath;  
  28.     CGPathRelease(circlePath);  
  29. }  



 

Layer Masking

 

例子4.5

 

 

  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIImageView *imageView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //create mask layer  
  14.     CALayer *maskLayer = [CALayer layer];  
  15.     maskLayer.frame = self.imageView.bounds;  
  16.     UIImage *maskImage = [UIImage imageNamed:@"Cone.png"];  
  17.     maskLayer.contents = (__bridge id)maskImage.CGImage;  
  18.       
  19.     //apply mask to image layer  
  20.     self.imageView.layer.mask = maskLayer;  
  21. }  
  22.   
  23. @end  

 



Scaling Filters

minificationFilter和magnificationFilter属性

这两个属性主要是设置layer的‘contents’数据缩放拉伸时的描绘方式,minificationFilter用于缩小,magnificationFilter用于放大

默认值都是kCAFilterLinear即‘linear’

有3中设置:kCAFilterLinear,kCAFilterNearest,kCAFilterTrilinear

kCAFilterLinear:默认值,缩放平滑,但容易产生模糊效果

kCAFilterTrilinear:基本和kCAFilterLinear相同

kCAFilterNearest:速度快不会产生模糊,但会降低质量并像素化图像

 

例子4.6,放大图像,设置magnificationFilter

原图   

 

  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, strong) IBOutletCollection(UIView) NSArray *digitViews;  
  4. @property (nonatomic, weak) NSTimer *timer;  
  5.   
  6. @end  
  7.   
  8. @implementation ViewController  
  9.   
  10. - (void)viewDidLoad  
  11. {  
  12.     [super viewDidLoad];  
  13.       
  14.     //get spritesheet image  
  15.     UIImage *digits = [UIImage imageNamed:@"Digits.png"];  
  16.       
  17.     //set up digit views  
  18.     for (UIView *view in self.digitViews)  
  19.     {  
  20.         //set contents  
  21.         view.layer.contents = (__bridge  id)digits.CGImage;  
  22.         view.layer.contentsRect = CGRectMake(0, 0, 0.1, 1.0);  
  23.         view.layer.contentsGravity = kCAGravityResizeAspect;  
  24.           
  25.         //use nearest-neighbor scaling  
  26.         view.layer.magnificationFilter = kCAFilterNearest;  
  27.     }  
  28.       
  29.     //start timer  
  30.     self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0  
  31.                                                   target:self  
  32.                                                 selector:@selector(tick)  
  33.                                                 userInfo:nil  
  34.                                                  repeats:YES];  
  35.     //set initial clock time  
  36.     [self tick];  
  37. }  
  38.   
  39. - (void)setDigit:(NSInteger)digit forView:(UIView *)view  
  40. {  
  41.     //adjust contentsRect to select correct digit  
  42.     view.layer.contentsRect = CGRectMake(digit * 0.1, 0, 0.1, 1.0);  
  43. }  
  44.   
  45. - (void)tick  
  46. {  
  47.     //convert time to hours, minutes and seconds  
  48.     NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];  
  49.     NSUInteger units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;  
  50.     NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];  
  51.       
  52.     //set hours  
  53.     [self setDigit:components.hour / 10 forView:self.digitViews[0]];  
  54.     [self setDigit:components.hour % 10 forView:self.digitViews[1]];  
  55.       
  56.     //set minutes  
  57.     [self setDigit:components.minute / 10 forView:self.digitViews[2]];  
  58.     [self setDigit:components.minute % 10 forView:self.digitViews[3]];  
  59.       
  60.     //set seconds  
  61.     [self setDigit:components.second / 10 forView:self.digitViews[4]];  
  62.     [self setDigit:components.second % 10 forView:self.digitViews[5]];  
  63. }  
  64.   
  65. @end  

kCAFilterNearest的效果

 


注释掉

 

  1. //view.layer.magnificationFilter = kCAFilterNearest;  

 

使用用默认kCAFilterLinear效果

 

明显模糊了

 

Group Opacity

先看例子4.7:

 

  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *containerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (UIButton *)customButton  
  10. {  
  11.     //create button  
  12.     CGRect frame = CGRectMake(0, 0, 150, 50);  
  13.     UIButton *button = [[UIButton alloc] initWithFrame:frame];  
  14.     button.backgroundColor = [UIColor whiteColor];  
  15.     button.layer.cornerRadius = 10;  
  16.       
  17.     //add label  
  18.     frame = CGRectMake(20, 10, 110, 30);  
  19.     UILabel *label = [[UILabel alloc] initWithFrame:frame];  
  20.     label.text = @"Hello World";  
  21.     //label.backgroundColor = [UIColor clearColor];  
  22.     label.textAlignment = NSTextAlignmentCenter;  
  23.     [button addSubview:label];  
  24.       
  25.     return button;  
  26. }  
  27.   
  28. - (void)viewDidLoad  
  29. {  
  30.     [super viewDidLoad];  
  31.       
  32.     //create opaque button  
  33.     UIButton *button1 = [self customButton];  
  34.     button1.center = CGPointMake(50, 150);  
  35.     [self.containerView addSubview:button1];  
  36.       
  37.     //create translucent button  
  38.     UIButton *button2 = [self customButton];  
  39.     button2.center = CGPointMake(250, 150);  
  40.     button2.alpha = 0.5;  
  41.     [self.containerView addSubview:button2];  
  42.       
  43.     //enable rasterization for the translucent button  
  44.     //button2.layer.shouldRasterize = YES;  
  45.     //button2.layer.rasterizationScale = [UIScreen mainScreen].scale;  
  46. }  
  47.   
  48. @end  


button的背景和其subView label的背景同为白色,

 

左边的button是不透明的,右边用同样方式创建的button透明度为50%,发现右边的label透明度不同于button

其实很容易发现原因,将button透明度设为50%后,button显示50%自己的颜色和其后面50%的颜色,label在

button上面,label也是50%显示择机的颜色,但后面有已经50%透明的button,还要再显示它的50%,即原

button的25%,重合后为75%,即出现上图效果。

有两种解决方法:

1.在工程的Info.plist文件中,添加UIViewGroupOpacity并设为YES

2.设置layer属性shouldRasterize,设为YES可在设置opacity属性时将layer及其sublayer叠加为一张图像

修改代码,

 

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //create opaque button  
  6.     UIButton *button1 = [self customButton];  
  7.     button1.center = CGPointMake(50, 150);  
  8.     [self.containerView addSubview:button1];  
  9.       
  10.     //create translucent button  
  11.     UIButton *button2 = [self customButton];  
  12.     button2.center = CGPointMake(250, 150);  
  13.     button2.alpha = 0.5;  
  14.     [self.containerView addSubview:button2];  
  15.       
  16.     //enable rasterization for the translucent button  
  17.     button2.layer.shouldRasterize = YES;  
  18.     button2.layer.rasterizationScale = [UIScreen mainScreen].scale;  
  19. }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值