第四章:Visual Effectsgit
Rounded Cornersxcode
例子4.1 cornerRadiusapp
源碼在這裏下載:http://www.informit.com/title/9780133440751svg
- #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];
-
-
- self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
-
-
- self.layerView2.layer.masksToBounds = YES;
- }
-
- @end
稍微修改一下函數
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
- self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
-
- self.layerView1.clipsToBounds = YES;
-
-
- self.layerView2.layer.masksToBounds = YES;
- }
前面講過了,UIView的clipsToBounds的函數等同於masksToBounds
Layer Borders
例子4.2 borderWidthoop
- @interface ViewController ()
-
- @property (nonatomic, weak) IBOutlet UIView *layerView1;
- @property (nonatomic, weak) IBOutlet UIView *layerView2;
-
- @end
-
- @implementation ViewController
-
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
- self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
-
-
- self.layerView1.layer.borderWidth = 5.0f;
- self.layerView2.layer.borderWidth = 5.0f;
-
-
- self.layerView2.layer.masksToBounds = YES;
- }
-
- @end
修改代碼 borderColoratom
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
- self.layerView1.layer.cornerRadius = 20.0f;
- self.layerView2.layer.cornerRadius = 20.0f;
-
-
- self.layerView1.layer.borderWidth = 5.0f;
- self.layerView1.layer.borderColor = [UIColor brownColor].CGColor;
- self.layerView2.layer.borderWidth = 5.0f;
-
-
- self.layerView2.layer.masksToBounds = YES;
- }
再作個試驗,修改代碼spa
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
-
- self.layerView2.layer.cornerRadius = 20.0f;
-
-
- self.layerView1.layer.borderWidth = 5.0f;
- self.layerView1.layer.borderColor = [UIColor brownColor].CGColor;
- self.layerView2.layer.borderWidth = 5.0f;
-
-
- self.layerView2.layer.masksToBounds = YES;
- }
沒有看到紅色.net
再修改rest
看結果
驗證borderWidth是往內部畫的,和使用CGContextStrokeEllipseInRect畫圓時的方式不一樣
Drop Shadows & Shadow Clipping
先修改例子2.2
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
- UIImage *image = [UIImage imageNamed:@"Snowman.png"];
-
- self.layerView.backgroundColor = [UIColor clearColor];
-
-
- self.layerView.layer.contents = (__bridge id)image.CGImage;
-
-
- self.layerView.layer.contentsGravity = kCAGravityCenter;
-
-
- self.layerView.layer.contentsScale = image.scale;
-
- self.layerView.layer.shadowOpacity = 0.3;
- self.layerView.layer.shadowOffset = CGSizeMake(10, 20);
-
-
-
- }
繼續
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
- UIImage *image = [UIImage imageNamed:@"Snowman.png"];
-
-
-
-
- self.layerView.layer.contents = (__bridge id)image.CGImage;
-
-
- self.layerView.layer.contentsGravity = kCAGravityCenter;
-
-
- self.layerView.layer.contentsScale = image.scale;
-
- self.layerView.layer.shadowOpacity = 0.3;
- self.layerView.layer.shadowOffset = CGSizeMake(10, 20);
-
-
-
- }
再改
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
- UIImage *image = [UIImage imageNamed:@"Snowman.png"];
-
- self.layerView.backgroundColor = [UIColor clearColor];
-
-
- self.layerView.layer.contents = (__bridge id)image.CGImage;
-
-
- self.layerView.layer.contentsGravity = kCAGravityCenter;
-
-
- self.layerView.layer.contentsScale = image.scale;
-
- self.layerView.layer.shadowOpacity = 0.3;
- self.layerView.layer.shadowOffset = CGSizeMake(10, 20);
-
-
- self.layerView.layer.masksToBounds = YES;
- }
再改
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
- UIImage *image = [UIImage imageNamed:@"Snowman.png"];
-
-
-
-
- self.layerView.layer.contents = (__bridge id)image.CGImage;
-
-
- self.layerView.layer.contentsGravity = kCAGravityCenter;
-
-
- self.layerView.layer.contentsScale = image.scale;
-
- self.layerView.layer.shadowOpacity = 0.3;
- self.layerView.layer.shadowOffset = CGSizeMake(10, 20);
-
-
- 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];
-
-
- self.layerView1.layer.shadowOpacity = 0.5f;
- self.layerView2.layer.shadowOpacity = 0.5f;
-
-
- CGMutablePathRef squarePath = CGPathCreateMutable();
- CGPathAddRect(squarePath, NULL, self.layerView1.bounds);
- self.layerView1.layer.shadowPath = squarePath;
- CGPathRelease(squarePath);
-
-
- 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];
-
-
- CALayer *maskLayer = [CALayer layer];
- maskLayer.frame = self.imageView.bounds;
- UIImage *maskImage = [UIImage imageNamed:@"Cone.png"];
- maskLayer.contents = (__bridge id)maskImage.CGImage;
-
-
- 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];
-
-
- UIImage *digits = [UIImage imageNamed:@"Digits.png"];
-
-
- for (UIView *view in self.digitViews)
- {
-
- view.layer.contents = (__bridge id)digits.CGImage;
- view.layer.contentsRect = CGRectMake(0, 0, 0.1, 1.0);
- view.layer.contentsGravity = kCAGravityResizeAspect;
-
-
- view.layer.magnificationFilter = kCAFilterNearest;
- }
-
-
- self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
- target:self
- selector:@selector(tick)
- userInfo:nil
- repeats:YES];
-
- [self tick];
- }
-
- - (void)setDigit:(NSInteger)digit forView:(UIView *)view
- {
-
- view.layer.contentsRect = CGRectMake(digit * 0.1, 0, 0.1, 1.0);
- }
-
- - (void)tick
- {
-
- NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
- NSUInteger units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
- NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
-
-
- [self setDigit:components.hour / 10 forView:self.digitViews[0]];
- [self setDigit:components.hour % 10 forView:self.digitViews[1]];
-
-
- [self setDigit:components.minute / 10 forView:self.digitViews[2]];
- [self setDigit:components.minute % 10 forView:self.digitViews[3]];
-
-
- [self setDigit:components.second / 10 forView:self.digitViews[4]];
- [self setDigit:components.second % 10 forView:self.digitViews[5]];
- }
-
- @end
kCAFilterNearest的效果
註釋掉
使用用默認kCAFilterLinear效果
明顯模糊了
Group Opacity
先看例子4.7:
- @interface ViewController ()
-
- @property (nonatomic, weak) IBOutlet UIView *containerView;
-
- @end
-
- @implementation ViewController
-
- - (UIButton *)customButton
- {
-
- CGRect frame = CGRectMake(0, 0, 150, 50);
- UIButton *button = [[UIButton alloc] initWithFrame:frame];
- button.backgroundColor = [UIColor whiteColor];
- button.layer.cornerRadius = 10;
-
-
- frame = CGRectMake(20, 10, 110, 30);
- UILabel *label = [[UILabel alloc] initWithFrame:frame];
- label.text = @"Hello World";
-
- label.textAlignment = NSTextAlignmentCenter;
- [button addSubview:label];
-
- return button;
- }
-
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
-
- UIButton *button1 = [self customButton];
- button1.center = CGPointMake(50, 150);
- [self.containerView addSubview:button1];
-
-
- UIButton *button2 = [self customButton];
- button2.center = CGPointMake(250, 150);
- button2.alpha = 0.5;
- [self.containerView addSubview:button2];
-
-
-
-
- }
-
- @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];
-
-
- UIButton *button1 = [self customButton];
- button1.center = CGPointMake(50, 150);
- [self.containerView addSubview:button1];
-
-
- UIButton *button2 = [self customButton];
- button2.center = CGPointMake(250, 150);
- button2.alpha = 0.5;
- [self.containerView addSubview:button2];
-
-
- button2.layer.shouldRasterize = YES;
- button2.layer.rasterizationScale = [UIScreen mainScreen].scale;
- }