IOS Core Animation Advanced Techniques的学习笔记(三)
第四章:Visual Effects
Rounded Corners
例子4.1 cornerRadius
源码在这里下载:http://www.informit.com/title/9780133440751
- #import "ViewController.h"
- #import <QuartzCore/QuartzCore.h>
- @interface ViewController ()
- @property (nonatomic, weak) IBOutlet UIView *layerView1;
- @property (nonatomic, weak) IBOutlet UIView *layerView2;
- @end
- @implementation ViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //set the corner radius on our layers
- self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
- //enable clipping on the second layer
- self.layerView2.layer.masksToBounds = YES;
- }
- @end
稍微修改一下
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //set the corner radius on our layers
- self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
- self.layerView1.clipsToBounds = YES;
- //enable clipping on the second layer
- self.layerView2.layer.masksToBounds = YES;
- }
前面讲过了,UIView的clipsToBounds的函数等同于masksToBounds
Layer Borders
例子4.2 borderWidth
- @interface ViewController ()
- @property (nonatomic, weak) IBOutlet UIView *layerView1;
- @property (nonatomic, weak) IBOutlet UIView *layerView2;
- @end
- @implementation ViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //set the corner radius on our layers
- self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
- //add a border to our layers
- self.layerView1.layer.borderWidth = 5.0f;
- self.layerView2.layer.borderWidth = 5.0f;
- //enable clipping on the second layer
- self.layerView2.layer.masksToBounds = YES;
- }
- @end
修改代码 borderColor
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //set the corner radius on our layers
- self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
- //add a border to our layers
- self.layerView1.layer.borderWidth = 5.0f;
- self.layerView1.layer.borderColor = [UIColor brownColor].CGColor;
- self.layerView2.layer.borderWidth = 5.0f;
- //enable clipping on the second layer
- self.layerView2.layer.masksToBounds = YES;
- }
再做个试验,修改代码
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //set the corner radius on our layers
- //self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
- //add a border to our layers
- self.layerView1.layer.borderWidth = 5.0f;
- self.layerView1.layer.borderColor = [UIColor brownColor].CGColor;
- self.layerView2.layer.borderWidth = 5.0f;
- //enable clipping on the second layer
- self.layerView2.layer.masksToBounds = YES;
- }
没有看到红色
再修改
看结果
验证borderWidth是往内部画的,和使用CGContextStrokeEllipseInRect画圆时的方式不同
Drop Shadows & Shadow Clipping
先修改例子2.2
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //load an image
- UIImage *image = [UIImage imageNamed:@"Snowman.png"];
- self.layerView.backgroundColor = [UIColor clearColor];
- //add it directly to our view's layer
- self.layerView.layer.contents = (__bridge id)image.CGImage;
- //center the image
- self.layerView.layer.contentsGravity = kCAGravityCenter;
- //set the contentsScale to match screen
- self.layerView.layer.contentsScale = image.scale;
- self.layerView.layer.shadowOpacity = 0.3;
- self.layerView.layer.shadowOffset = CGSizeMake(10, 20);
- //clip the snowman to fit his bounds
- //self.layerView.layer.masksToBounds = YES;
- }
继续
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //load an image
- UIImage *image = [UIImage imageNamed:@"Snowman.png"];
- //self.layerView.backgroundColor = [UIColor clearColor];
- //add it directly to our view's layer
- self.layerView.layer.contents = (__bridge id)image.CGImage;
- //center the image
- self.layerView.layer.contentsGravity = kCAGravityCenter;
- //set the contentsScale to match screen
- self.layerView.layer.contentsScale = image.scale;
- self.layerView.layer.shadowOpacity = 0.3;
- self.layerView.layer.shadowOffset = CGSizeMake(10, 20);
- //clip the snowman to fit his bounds
- //self.layerView.layer.masksToBounds = YES;
- }
再改
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //load an image
- UIImage *image = [UIImage imageNamed:@"Snowman.png"];
- self.layerView.backgroundColor = [UIColor clearColor];
- //add it directly to our view's layer
- self.layerView.layer.contents = (__bridge id)image.CGImage;
- //center the image
- self.layerView.layer.contentsGravity = kCAGravityCenter;
- //set the contentsScale to match screen
- self.layerView.layer.contentsScale = image.scale;
- self.layerView.layer.shadowOpacity = 0.3;
- self.layerView.layer.shadowOffset = CGSizeMake(10, 20);
- //clip the snowman to fit his bounds
- self.layerView.layer.masksToBounds = YES;
- }
再改
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //load an image
- UIImage *image = [UIImage imageNamed:@"Snowman.png"];
- //self.layerView.backgroundColor = [UIColor clearColor];
- //add it directly to our view's layer
- self.layerView.layer.contents = (__bridge id)image.CGImage;
- //center the image
- self.layerView.layer.contentsGravity = kCAGravityCenter;
- //set the contentsScale to match screen
- self.layerView.layer.contentsScale = image.scale;
- self.layerView.layer.shadowOpacity = 0.3;
- self.layerView.layer.shadowOffset = CGSizeMake(10, 20);
- //clip the snowman to fit his bounds
- self.layerView.layer.masksToBounds = YES;
- }
shadow是根据layer实际显示的内容绘制的
再看看例子4.3去体会一下
源码在这里下载:http://www.informit.com/title/9780133440751
The shadowPath Property
例子4.4
- @interface ViewController ()
- @property (nonatomic, weak) IBOutlet UIView *layerView1;
- @property (nonatomic, weak) IBOutlet UIView *layerView2;
- @end
- @implementation ViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //enable layer shadows
- self.layerView1.layer.shadowOpacity = 0.5f;
- self.layerView2.layer.shadowOpacity = 0.5f;
- //create a square shadow
- CGMutablePathRef squarePath = CGPathCreateMutable();
- CGPathAddRect(squarePath, NULL, self.layerView1.bounds);
- self.layerView1.layer.shadowPath = squarePath;
- CGPathRelease(squarePath);
- //create a circular shadow
- CGMutablePathRef circlePath = CGPathCreateMutable();
- CGPathAddEllipseInRect(circlePath, NULL, self.layerView2.bounds);
- self.layerView2.layer.shadowPath = circlePath;
- CGPathRelease(circlePath);
- }
Layer Masking
例子4.5
- @interface ViewController ()
- @property (nonatomic, weak) IBOutlet UIImageView *imageView;
- @end
- @implementation ViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //create mask layer
- CALayer *maskLayer = [CALayer layer];
- maskLayer.frame = self.imageView.bounds;
- UIImage *maskImage = [UIImage imageNamed:@"Cone.png"];
- maskLayer.contents = (__bridge id)maskImage.CGImage;
- //apply mask to image layer
- self.imageView.layer.mask = maskLayer;
- }
- @end
Scaling Filters
minificationFilter和magnificationFilter属性
这两个属性主要是设置layer的‘contents’数据缩放拉伸时的描绘方式,minificationFilter用于缩小,magnificationFilter用于放大
默认值都是kCAFilterLinear即‘linear’
有3中设置:kCAFilterLinear,kCAFilterNearest,kCAFilterTrilinear
kCAFilterLinear:默认值,缩放平滑,但容易产生模糊效果
kCAFilterTrilinear:基本和kCAFilterLinear相同
kCAFilterNearest:速度快不会产生模糊,但会降低质量并像素化图像
例子4.6,放大图像,设置magnificationFilter
原图
- @interface ViewController ()
- @property (nonatomic, strong) IBOutletCollection(UIView) NSArray *digitViews;
- @property (nonatomic, weak) NSTimer *timer;
- @end
- @implementation ViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //get spritesheet image
- UIImage *digits = [UIImage imageNamed:@"Digits.png"];
- //set up digit views
- for (UIView *view in self.digitViews)
- {
- //set contents
- view.layer.contents = (__bridge id)digits.CGImage;
- view.layer.contentsRect = CGRectMake(0, 0, 0.1, 1.0);
- view.layer.contentsGravity = kCAGravityResizeAspect;
- //use nearest-neighbor scaling
- view.layer.magnificationFilter = kCAFilterNearest;
- }
- //start timer
- self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
- target:self
- selector:@selector(tick)
- userInfo:nil
- repeats:YES];
- //set initial clock time
- [self tick];
- }
- - (void)setDigit:(NSInteger)digit forView:(UIView *)view
- {
- //adjust contentsRect to select correct digit
- view.layer.contentsRect = CGRectMake(digit * 0.1, 0, 0.1, 1.0);
- }
- - (void)tick
- {
- //convert time to hours, minutes and seconds
- NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
- NSUInteger units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
- NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
- //set hours
- [self setDigit:components.hour / 10 forView:self.digitViews[0]];
- [self setDigit:components.hour % 10 forView:self.digitViews[1]];
- //set minutes
- [self setDigit:components.minute / 10 forView:self.digitViews[2]];
- [self setDigit:components.minute % 10 forView:self.digitViews[3]];
- //set seconds
- [self setDigit:components.second / 10 forView:self.digitViews[4]];
- [self setDigit:components.second % 10 forView:self.digitViews[5]];
- }
- @end
kCAFilterNearest的效果
注释掉
- //view.layer.magnificationFilter = kCAFilterNearest;
使用用默认kCAFilterLinear效果
明显模糊了
Group Opacity
先看例子4.7:
- @interface ViewController ()
- @property (nonatomic, weak) IBOutlet UIView *containerView;
- @end
- @implementation ViewController
- - (UIButton *)customButton
- {
- //create button
- CGRect frame = CGRectMake(0, 0, 150, 50);
- UIButton *button = [[UIButton alloc] initWithFrame:frame];
- button.backgroundColor = [UIColor whiteColor];
- button.layer.cornerRadius = 10;
- //add label
- frame = CGRectMake(20, 10, 110, 30);
- UILabel *label = [[UILabel alloc] initWithFrame:frame];
- label.text = @"Hello World";
- //label.backgroundColor = [UIColor clearColor];
- label.textAlignment = NSTextAlignmentCenter;
- [button addSubview:label];
- return button;
- }
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //create opaque button
- UIButton *button1 = [self customButton];
- button1.center = CGPointMake(50, 150);
- [self.containerView addSubview:button1];
- //create translucent button
- UIButton *button2 = [self customButton];
- button2.center = CGPointMake(250, 150);
- button2.alpha = 0.5;
- [self.containerView addSubview:button2];
- //enable rasterization for the translucent button
- //button2.layer.shouldRasterize = YES;
- //button2.layer.rasterizationScale = [UIScreen mainScreen].scale;
- }
- @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叠加为一张图像
修改代码,
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //create opaque button
- UIButton *button1 = [self customButton];
- button1.center = CGPointMake(50, 150);
- [self.containerView addSubview:button1];
- //create translucent button
- UIButton *button2 = [self customButton];
- button2.center = CGPointMake(250, 150);
- button2.alpha = 0.5;
- [self.containerView addSubview:button2];
- //enable rasterization for the translucent button
- button2.layer.shouldRasterize = YES;
- button2.layer.rasterizationScale = [UIScreen mainScreen].scale;
- }
IOS Core Animation Advanced Techniques的学习笔记(三)的更多相关文章
- IOS Core Animation Advanced Techniques的学习笔记(一)
转载. Book Description Publication Date: August 12, 2013 Core Animation is the technology underlying A ...
- IOS Core Animation Advanced Techniques的学习笔记(五)
第六章:Specialized Layers 类别 用途 CAEmitterLayer 用于实现基于Core Animation粒子发射系统.发射器层对象控制粒子的生成和起源 CAGradient ...
- IOS Core Animation Advanced Techniques的学习笔记(四)
第五章:Transforms Affine Transforms CGAffineTransform是二维的 Creating a CGAffineTransform 主要有三种变 ...
- IOS Core Animation Advanced Techniques的学习笔记(二)
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { CGFloat width = 10.0f; //draw a thi ...
- iOS Core Animation Advanced Techniques
Book Descripter Core Animation is the technology underlying Apple's iOS user interface. By unleashin ...
- 转 iOS Core Animation 动画 入门学习(一)基础
iOS Core Animation 动画 入门学习(一)基础 reference:https://developer.apple.com/library/ios/documentation/Coco ...
- iOS Core Animation 简明系列教程
iOS Core Animation 简明系列教程 看到无数的CA教程,都非常的难懂,各种事务各种图层关系看的人头大.自己就想用通俗的语言翻译给大家听,尽可能准确表达,如果哪里有问题,请您指出我会尽 ...
- iOS - Core Animation 核心动画
1.UIView 动画 具体讲解见 iOS - UIView 动画 2.UIImageView 动画 具体讲解见 iOS - UIImageView 动画 3.CADisplayLink 定时器 具体 ...
- iOS安全些许经验和学习笔记
http://bbs.pediy.com/showthread.php?t=209014 标题: [原创]iOS安全些许经验和学习笔记作者: MonkeyKey时间: 2016-03-30,16:32 ...
随机推荐
- Boost学习笔记(一) 什么是Boost
Boost库是一个功能强大.构造精巧,跨平台.开源并且完全免费的C++程序库
- Js零散知识点笔记
1.将类数组对象转换为数组 ES5: var arrLike = document.querySelectorAll('span'); var arr = Array.prototype.slice. ...
- 记SpannableString设多少span时注意事项
public void setSpan(Object what, int start, int end, int flags) { } 这个方法里的第一个参数,也就是一些span的对象,不能重复使用. ...
- 安装composer
按照composer官网的指导,运行下列命令:curl -sS https://getcomposer.org/installer | php长时间无反应.手动安装1.下载installer# wge ...
- hdu4449Building Design(三维凸包+平面旋转)
链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...
- 利用Github Pages生成一个快速访问的网址,展示自己的项目
利用Github Pages展示自己的项目 写了个小项目,想要分享出去,一直在用Github管理项目,了解到Github还有Github Pages功能,然后惊喜的发现Github pages可以搭建 ...
- stm32定时器中断类型分析
一直在用的stm32定时器的中断都是TIM_IT_Update更新中断,也没问为什么,直到碰到有人使用TIM_IT_CC1中断,才想到这定时器的中断类型究竟有什么区别,都怪当时学习stm32的时候不够 ...
- 使用Let`s encrypt 免费的https 证书
在iOS上以前暂时屏蔽https使用http的接口,将在未来被苹果拒绝: 之前传苹果会在2017年1月1日强制要求支持https,但是现在苹果又延迟该计划了 https://developer.app ...
- IDEA建立---- java web项目
1.新建一个javaweb项目 2.给项目命名 3.建立完的项目结构大概是这样(在web 下新建 两个目录lib 和 classes) 4.找到project Structure---------&g ...
- 卸载mysql
如果你的电脑里装过MySQL,想再重新安装MySQL的时候可能就会因为前一版本卸载不彻底而出现错误.最常见的就是安装好后设置参数的最后一步验证时,会在Execute configurattion步骤中 ...