ios layer.mask
来源:互联网 发布:淘宝上店铺获取失败 编辑:程序博客网 时间:2024/06/05 00:41
二、文字渐变实现思路:
1.创建一个颜色渐变层,渐变图层跟文字控件一样大。
2.用文字图层裁剪渐变层,只保留文字部分,就会让渐变层只保留有文字的部分,相当于间接让渐变层显示文字,我们看到的其实是被裁剪过后,渐变层的部分内容。
注意:如果用文字图层裁剪渐变层,文字图层就不在拥有显示功能,这个图层就被弄来裁剪了,不会显示,在下面代码中也会有说明。
2.1 创建一个带有文字的label,label能显示文字。
2.2 设置渐变图层的mask为label图层,就能用文字裁剪渐变图层了。
3.mask图层工作原理:
1.根据透明度进行裁剪,只保留非透明部分,显示底部内容。
4.详细代码+解释
// 创建UILabel
UILabel *label = [[YZLabel alloc] init];
label.text = @
"小码哥,专注于高级iOS开发工程师的培养"
;
[label sizeToFit];
label.center = CGPointMake(200, 100);
// 疑问:label只是用来做文字裁剪,能否不添加到view上。
// 必须要把Label添加到view上,如果不添加到view上,
label的图层就不会调用drawRect方法绘制文字,也就没有文字裁剪了。
// 如何验证,自定义Label,重写drawRect方法,看是否调用,发现不添加上去,就不会调用
[self.view addSubview:label];
// 创建渐变层
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = label.frame;
// 设置渐变层的颜色,随机颜色渐变
gradientLayer.colors = @[(id)[self randomColor].CGColor, (id)[self randomColor].CGColor,(id)[self randomColor].CGColor];
// 疑问:渐变层能不能加在label上
// 不能,mask原理:默认会显示mask层底部的内容,如果渐变层放在mask层上,就不会显示了
// 添加渐变层到控制器的view图层上
[self.view.layer addSublayer:gradientLayer];
// mask层工作原理:按照透明度裁剪,只保留非透明部分,文字就是非透明的,因此除了文字,其他都被裁剪掉,
这样就只会显示文字下面渐变层的内容,相当于留了文字的区域,让渐变层去填充文字的颜色。
// 设置渐变层的裁剪层
gradientLayer.mask = label.layer;
// 注意:一旦把label层设置为mask层,label层就不能显示了,会直接从父层中移除,然后作为渐变层的mask层,
且label层的父层会指向渐变层,
这样做的目的:以渐变层为坐标系,方便计算裁剪区域,如果以其他层为坐标系,还需要做点的转换,需要把别的坐标系上的点,转换成自己坐标系上点,
判断当前点在不在裁剪范围内,比较麻烦。
// 父层改了,坐标系也就改了,需要重新设置label的位置,才能正确的设置裁剪区域。
label.frame = gradientLayer.bounds;
#import "LXGradientProcessView.h"#import "UIView+Extensions.h"#import "UIColor+Extensions.h"static const CGFloat kProcessHeight = 10.f;static const CGFloat kTopSpaces = 5.f;static const CGFloat kNumberMarkWidth = 60.f;static const CGFloat kNumberMarkHeight = 20.f;static const CGFloat kAnimationTime = 3.f;@interface LXGradientProcessView ()@property (nonatomic, strong) CALayer *maskLayer;@property (nonatomic, strong) CAGradientLayer *gradientLayer;@property (nonatomic, strong) UIButton *numberMark; // 数字标示@property (nonatomic, strong) NSTimer *numberChangeTimer;@property (nonatomic, assign) CGFloat numberPercent;@property (nonatomic, strong) NSArray *colorArray;@property (nonatomic, strong) NSArray *colorLocationArray;@end@implementation LXGradientProcessView- (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor whiteColor]; self.colorArray = @[(id)[[UIColor colorWithHex:0xFF6347] CGColor], (id)[[UIColor colorWithHex:0xFFEC8B] CGColor], (id)[[UIColor colorWithHex:0x98FB98] CGColor], (id)[[UIColor colorWithHex:0x00B2EE] CGColor], (id)[[UIColor colorWithHex:0x9400D3] CGColor]]; self.colorLocationArray = @[@0.1, @0.3, @0.5, @0.7, @1]; self.numberMark.frame = CGRectMake(0, kTopSpaces, kNumberMarkWidth, kNumberMarkHeight); [self addSubview:self.numberMark]; [self setNUmberMarkLayer]; [self getGradientLayer]; self.numberPercent = 0; } return self;}- (void)setNUmberMarkLayer { // 提示文字设置渐变色 CAGradientLayer *numberGradientLayer = [CAGradientLayer layer]; numberGradientLayer.frame = CGRectMake(0, kTopSpaces, self.width, kNumberMarkHeight); [numberGradientLayer setColors:self.colorArray]; [numberGradientLayer setLocations:self.colorLocationArray]; [numberGradientLayer setStartPoint:CGPointMake(0, 0)]; [numberGradientLayer setEndPoint:CGPointMake(1, 0)]; [self.layer addSublayer:numberGradientLayer]; [numberGradientLayer setMask:self.numberMark.layer]; self.numberMark.frame = numberGradientLayer.bounds; NSLog(@"numberMark = %@ numberGradientLayer = %@ ",NSStringFromCGRect(self.numberMark.frame),NSStringFromCGRect(numberGradientLayer.frame));}- (void)getGradientLayer{ // 进度条设置渐变色 // 灰色进度条背景 CALayer *bgLayer = [CALayer layer]; bgLayer.frame = CGRectMake(kNumberMarkWidth / 2, self.height - kProcessHeight - kTopSpaces, self.width - kNumberMarkWidth / 2, kProcessHeight); bgLayer.backgroundColor = [UIColor colorWithHex:0xF5F5F5].CGColor; bgLayer.masksToBounds = YES; bgLayer.cornerRadius = kProcessHeight / 2; [self.layer addSublayer:bgLayer]; self.maskLayer = [CALayer layer]; self.maskLayer.frame = CGRectMake(0, 0, (self.width - kNumberMarkWidth / 2) * self.percent / 100.f, kProcessHeight); self.maskLayer.borderWidth = self.height / 2; self.gradientLayer = [CAGradientLayer layer]; self.gradientLayer.frame = CGRectMake(kNumberMarkWidth / 2, self.height - kProcessHeight - kTopSpaces, self.width - kNumberMarkWidth / 2, kProcessHeight); self.gradientLayer.masksToBounds = YES; self.gradientLayer.cornerRadius = kProcessHeight / 2; [self.gradientLayer setColors:self.colorArray]; [self.gradientLayer setLocations:self.colorLocationArray]; [self.gradientLayer setStartPoint:CGPointMake(0, 0)]; [self.gradientLayer setEndPoint:CGPointMake(1, 0)]; [self.gradientLayer setMask:self.maskLayer]; [self.layer addSublayer:self.gradientLayer]; NSLog(@"maskLayer = %@ gradientLayer = %@ bgLayer = %@",NSStringFromCGRect(self.maskLayer.frame),NSStringFromCGRect(self.gradientLayer.frame),NSStringFromCGRect(bgLayer.frame));}- (void)setPercent:(CGFloat)percent { [self setPercent:percent animated:YES];}- (void)setPercent:(CGFloat)percent animated:(BOOL)animated { _percent = percent; [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(circleAnimation) userInfo:nil repeats:NO]; // 文字动画 __weak typeof(self)weakSelf = self; [UIView animateWithDuration:kAnimationTime animations:^{ weakSelf.numberMark.frame = CGRectMake((weakSelf.width - kNumberMarkWidth) * percent / 100, 0, kNumberMarkWidth, kNumberMarkHeight); // [weakSelf.numberMark setTitle:[NSString stringWithFormat:@"%.1f分",percent / 20.f] forState:UIControlStateNormal]; }]; self.numberChangeTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(changeNumber) userInfo:nil repeats:YES];}- (void)changeNumber { // 每0.1秒改变百分比文字 if (!self.percent) { [self.numberChangeTimer invalidate]; self.numberChangeTimer = nil; } self.numberPercent += (self.percent / (kAnimationTime * 10.f)); if (self.numberPercent > self.percent) { [self.numberChangeTimer invalidate]; self.numberChangeTimer = nil; self.numberPercent = self.percent; } [self.numberMark setTitle:[NSString stringWithFormat:@"%.1f",self.numberPercent] forState:UIControlStateNormal];}- (void)circleAnimation { // 进度条动画 [CATransaction begin]; [CATransaction setDisableActions:NO]; [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [CATransaction setAnimationDuration:kAnimationTime]; self.maskLayer.frame = CGRectMake(0, 0, (self.width - kNumberMarkWidth / 2) * _percent / 100.f, kProcessHeight); [CATransaction commit];}- (UIButton *)numberMark { if (nil == _numberMark) { _numberMark = [UIButton buttonWithType:UIButtonTypeCustom]; [_numberMark setTitle:@"0分" forState:UIControlStateNormal]; [_numberMark setTitleColor:[UIColor colorWithHex:0xFF6347] forState:UIControlStateNormal]; [_numberMark setBackgroundImage:[UIImage imageNamed:@"user_score_bubble"] forState:UIControlStateNormal]; _numberMark.titleLabel.font = [UIFont systemFontOfSize:13.f]; _numberMark.enabled = NO; } return _numberMark;}
// 渐变进度条 self.processView = [[LXGradientProcessView alloc] initWithFrame:CGRectMake(20.f, 100.f, SCREEN_WIDTH - 40.f, 45.f)]; self.processView.percent = 0; [self.view addSubview:self.processView]; UIButton *stareButton = [UIButton buttonWithType:UIButtonTypeSystem]; [stareButton setFrame:CGRectMake(20.f, 300.f, SCREEN_WIDTH - 40.f, 38.f)]; [stareButton addTarget:self action:@selector(onStareButtonClick) forControlEvents:UIControlEventTouchUpInside]; [stareButton setTitle:@"Stare" forState:UIControlStateNormal]; stareButton.layer.cornerRadius = 4.f; stareButton.layer.borderWidth = 0.5; stareButton.layer.borderColor = [UIColor lightGrayColor].CGColor; [self.view addSubview:stareButton];
//镂空
- (void)addMask{ UIButton * _maskButton = [[UIButton alloc] init]; [_maskButton setFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)]; [_maskButton setBackgroundColor:[UIColor colorWithWhite:0 alpha:0.7]]; [self.view addSubview:_maskButton]; //create path UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)]; // MARK: circlePath [path appendPath:[UIBezierPath bezierPathWithArcCenter:CGPointMake(SCREEN_WIDTH / 2, 200) radius:100 startAngle:0 endAngle:2*M_PI clockwise:NO]]; // MARK: roundRectanglePath [path appendPath:[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 400, SCREEN_WIDTH - 22 * 20, 100) cornerRadius:15] bezierPathByReversingPath]]; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = path.CGPath; [_maskButton.layer setMask:shapeLayer]; maskLayer = shapeLayer;}
//文字变色
UILabel *_numberMark = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 10, 50)]; _numberMark.textAlignment = NSTextAlignmentLeft; _numberMark.text = @"aa"; textLabel = _numberMark; CAGradientLayer *colorLayer = [CAGradientLayer layer]; colorLayer.frame = CGRectMake(0, 0, 300, 50); // 颜色分配 colorLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor greenColor].CGColor, (__bridge id)[UIColor blueColor].CGColor, (__bridge id)[UIColor redColor].CGColor]; // 颜色分割线 colorLayer.locations = @[@(0.25), @(0.5), @(0.75)]; // 起始点 colorLayer.startPoint = CGPointMake(0, 0); // 结束点 colorLayer.endPoint = CGPointMake(1, 0); [self.view.layer addSublayer:colorLayer]; colorLayer.mask = _numberMark.layer;
/1。弧度转角度#define pi 3.14159265359#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))//2。角度转弧度// Degrees to radians#define pi 3.14159265359#define DEGREES_TO_RADIANS(degrees) ((pi * degrees)/ 180)@implementation LTWiFiScanView- (id)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { } return self;}// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect { // Drawing code CALayer *superLayer = [CALayer layer]; superLayer.frame = self.frame; CAShapeLayer *layer = [CAShapeLayer layer]; layer.frame = CGRectMake(0, 0, rect.size.width/6, rect.size.height/6); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150,151) radius:2.5f startAngle:DEGREES_TO_RADIANS(220) endAngle:DEGREES_TO_RADIANS(320) clockwise:YES]; layer.path = path.CGPath; layer.lineWidth = 5; layer.strokeColor = [UIColor redColor].CGColor; layer.fillColor = [UIColor blueColor].CGColor; CAKeyframeAnimation *opacityAnimation = [CAKeyframeAnimation animation]; opacityAnimation.keyPath = @"opacity"; opacityAnimation.values = @[@1.0,@0.75,@0.5,@0.25,@0.0]; opacityAnimation.keyTimes = @[@0.0,@0.25,@0.5,@0.75,@1]; opacityAnimation.fillMode = kCAFillModeBoth; opacityAnimation.duration = 1; opacityAnimation.beginTime = CACurrentMediaTime() + (float) 0 * 1.5 / 3; opacityAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; opacityAnimation.autoreverses = NO; opacityAnimation.removedOnCompletion = NO; opacityAnimation.repeatCount = HUGE_VALF; // [layer addAnimation:opacityAnimation forKey:@"op"]; [superLayer addSublayer:layer]; CAShapeLayer *layer1 = [CAShapeLayer layer]; layer.frame = CGRectMake(0, 0, rect.size.width/6, rect.size.height/6); UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150,150) radius:10 startAngle:DEGREES_TO_RADIANS(220) endAngle:DEGREES_TO_RADIANS(320) clockwise:YES]; layer1.path = path1.CGPath; layer1.lineWidth = 5; layer1.strokeColor = [UIColor blueColor].CGColor; layer1.fillColor = [UIColor clearColor].CGColor; CAKeyframeAnimation *opacityAnimation1 = [CAKeyframeAnimation animation]; opacityAnimation1.keyPath = @"opacity"; opacityAnimation1.values = @[@1.0,@0.75,@0.5,@0.25,@0.0]; opacityAnimation1.keyTimes = @[@0.0,@0.25,@0.5,@0.75,@1]; opacityAnimation1.fillMode = kCAFillModeBoth; opacityAnimation1.duration = 1; opacityAnimation1.beginTime = CACurrentMediaTime() + (float) 1 * 1.5 / 3; opacityAnimation1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; opacityAnimation1.autoreverses = NO; opacityAnimation1.removedOnCompletion = NO; opacityAnimation1.repeatCount = HUGE_VALF;// [layer1 addAnimation:opacityAnimation1 forKey:@"op"]; [superLayer addSublayer:layer1]; CAShapeLayer *layer2 = [CAShapeLayer layer]; layer2.frame = CGRectMake(0, 0, rect.size.width/6, rect.size.height/6); UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150,150) radius:20 startAngle:DEGREES_TO_RADIANS(220) endAngle:DEGREES_TO_RADIANS(320) clockwise:YES]; layer2.path = path2.CGPath; layer2.lineWidth = 5; layer2.strokeColor = [UIColor blueColor].CGColor; layer2.fillColor = [UIColor clearColor].CGColor; CAKeyframeAnimation *opacityAnimation2 = [CAKeyframeAnimation animation]; opacityAnimation2.keyPath = @"opacity"; opacityAnimation2.values = @[@1.0,@0.75,@0.5,@0.25,@0.0]; opacityAnimation2.keyTimes = @[@0.0,@0.25,@0.5,@0.75,@1]; opacityAnimation2.fillMode = kCAFillModeBoth; opacityAnimation2.duration = 1; opacityAnimation2.beginTime = CACurrentMediaTime() + (float) 2 * 1.5 / 3; opacityAnimation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; opacityAnimation2.autoreverses = NO; opacityAnimation2.removedOnCompletion = NO; opacityAnimation2.repeatCount = HUGE_VALF;// [layer2 addAnimation:opacityAnimation2 forKey:@"op"]; [superLayer addSublayer:layer2]; [self.layer addSublayer:superLayer];
0 0
- iOS mask Layer 详解
- ios layer.mask
- ios layer.mask
- iOS:Layer.mask属性用法
- iOS mask layer的使用
- UIImageView 的 layer.mask
- mask 和 layer绘图相关
- iOS 利用mask layer 使view中扣掉一块露出下边的view
- iOS 利用mask layer 使view中扣掉一块露出下边的view
- iOS 利用mask layer 使view中扣掉一块露出下边的view
- 为什么layer的mask属性和photoshop的mask不一样
- JQuery api - loading mask layer on page
- Unity之EditorGUILayout-Layer、Mask、Tag
- iOS 遮罩(mask)效果
- ios CALayer mask使用
- iOS CALayer mask 属性
- IOS 屏幕遮罩 Mask
- mask
- Linux命令行与Shell脚本编程(续)
- DOM初体验——alert的是null
- UIView的alpha和 颜色的alpha的作用
- 水平划分和垂直划分
- .NET导出Gridview到excel 带模板列显示(未验证)
- ios layer.mask
- Python base64编码
- git学习--commit-msg缺失导致的missing Change-Id问题分析
- Java 字符串之String.split()方法产生的数组长度和期望值不一样的探究?
- Mac 模拟慢速网络
- 静态或者全局智能指针使用的注意几点
- Android中使用Parcelable实现对象的序列化
- 微信公众号运营心得
- 【设计模式】【七】装饰模式