• 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. }  

  • 相关阅读:
    【杭电】[1302]The Snail
    【Light】[1297]Largest Box
    ubuntu10.04安装putty以保存SSH会话
    印象笔记导入为知笔记方法
    HTTP返回状态码及错误大全
    Ubuntu14.04安装wineqq国际版
    Ubuntu Unity 桌面快捷键切换窗口技巧
    Ubuntu14.04下安装为知笔记
    在ubuntu中如何管理startup application
    Error:" Can't locate Term/ReadKey.pm in @INC" 的解决方法
  • 原文地址:https://www.cnblogs.com/geek6/p/3931094.html
Copyright © 2020-2023  润新知