第四章:Visual Effects

 

Rounded Corners

例子4.1 cornerRadius

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

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

稍微修改一下

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


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

Layer Borders

例子4.2 borderWidth

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

修改代码 borderColor

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

再做个试验,修改代码

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


没有看到红色

再修改

看结果

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

Drop Shadows & Shadow Clipping

先修改例子2.2

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

继续

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

再改

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

再改

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

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

再看看例子4.3去体会一下

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

 

The shadowPath Property

例子4.4

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

 

Layer Masking

例子4.5

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

kCAFilterNearest的效果


注释掉

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

使用用默认kCAFilterLinear效果

明显模糊了

Group Opacity

先看例子4.7:

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

IOS Core Animation Advanced Techniques的学习笔记(三)的更多相关文章

  1. IOS Core Animation Advanced Techniques的学习笔记(一)

    转载. Book Description Publication Date: August 12, 2013 Core Animation is the technology underlying A ...

  2. IOS Core Animation Advanced Techniques的学习笔记(五)

    第六章:Specialized Layers   类别 用途 CAEmitterLayer 用于实现基于Core Animation粒子发射系统.发射器层对象控制粒子的生成和起源 CAGradient ...

  3. IOS Core Animation Advanced Techniques的学习笔记(四)

    第五章:Transforms   Affine Transforms   CGAffineTransform是二维的     Creating a CGAffineTransform   主要有三种变 ...

  4. IOS Core Animation Advanced Techniques的学习笔记(二)

    - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { CGFloat width = 10.0f; //draw a thi ...

  5. iOS Core Animation Advanced Techniques

    Book Descripter Core Animation is the technology underlying Apple's iOS user interface. By unleashin ...

  6. 转 iOS Core Animation 动画 入门学习(一)基础

    iOS Core Animation 动画 入门学习(一)基础 reference:https://developer.apple.com/library/ios/documentation/Coco ...

  7. iOS Core Animation 简明系列教程

    iOS Core Animation 简明系列教程  看到无数的CA教程,都非常的难懂,各种事务各种图层关系看的人头大.自己就想用通俗的语言翻译给大家听,尽可能准确表达,如果哪里有问题,请您指出我会尽 ...

  8. iOS - Core Animation 核心动画

    1.UIView 动画 具体讲解见 iOS - UIView 动画 2.UIImageView 动画 具体讲解见 iOS - UIImageView 动画 3.CADisplayLink 定时器 具体 ...

  9. iOS安全些许经验和学习笔记

    http://bbs.pediy.com/showthread.php?t=209014 标题: [原创]iOS安全些许经验和学习笔记作者: MonkeyKey时间: 2016-03-30,16:32 ...

随机推荐

  1. 微信小程序开发感受

    研究了大概有一个多星期的小程序了,说一下感受,之后会随时更新,一边学习,一边加上一部分学习代码和心得.我是一个前端厂里的新手,搬砖的时间不是很长,所以到一部分知识的理解浅之又浅,所以只能说自己的理解, ...

  2. 话说C++中的左值、纯右值、将亡值

    写在前面 C++中有“左值”.“右值”的概念,C++11以后,又有了“左值”.“纯右值”.“将亡值”的概念.关于这些概念,许多资料上都有介绍,本文在拾人牙慧的基础上又加入了一些自己的一些理解,同时提出 ...

  3. 3.UIViewController详解

     一. UIViewController,视图控制器,它是UIKit中非常重要的组成部分.它由控制器+View两部分组成. 控制器功能: ->实现代码逻辑,决定它自带的View的界面显示. -& ...

  4. 16-阿里-intership

  5. Codeforces Round #385 (Div. 2) A,B,C 暴力,模拟,并查集

    A. Hongcow Learns the Cyclic Shift time limit per test 2 seconds memory limit per test 256 megabytes ...

  6. Java知识积累1-StringAlign实现文字居中左右对齐

    import java.text.*;public class StringAlign extends Format{ public static final int JUST_LEFT='l'; / ...

  7. mysql安装,配置。

    看到百度经验上有一篇文章比较好,后来发现是舍友写的,他同意后,便复制到我的博客园中,希望更多小白看到,原地址:http://jingyan.baidu.com/article/597035521d5d ...

  8. 基本shell命令使用笔记

    linux常用命令: (ls:列出目录内容) -a/-all 列出所有文件,包括隐藏文件 -l 使用长格式显示详细信息,包括rwx (mkdir:建立目录) -p/-parents 若要建立目录的上层 ...

  9. myeclipse连接oracle步骤

    1.加载ojdbc.jar驱动(路径:E:\myoracle\oracle\product\11.2.0\dbhome_1\jdbc\lib) 2.String url = "jdbc:or ...

  10. 【Java】需要注意的小细节

    一.==和equals 1.比较两个变量时 a.==可以判断两个变量是否相等,如果两个变量是基本类型变量,而且是数值类型,只要两个变量值相等,返回true. 2.比较两个引用变量 a.==只有两个引用 ...