iosiOS开发

图层与文字的完美设计

2017-03-09  本文已影响162人  阿文灬
图层与文字的完美设计1.png

我们先来一个简单的卡拉OK效果练练手吧

卡拉OK效果.gif

这个非常容易,设置定时器计算进度progress。重写UILabel的drawRect:,通过progress计算颜色区域,然后填充颜色就行,不过要注意一下填充方式。

// 这里计算字体大小与frame需要做一些优化。因为该方式调用非常多
- (void)setProgress:(CGFloat)progress{
    _progress = progress;
    if (_progress == 0) {
        [self setFont:[UIFont systemFontOfSize:14]];
    } else {
        [self setFont:[UIFont boldSystemFontOfSize:16]];
    }
    [self sizeToFit]; 
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    CGFloat width = self.frame.size.width * self.progress;
    CGRect colorRect = CGRectMake(0, 0, width, self.frame.size.height);
    
    if (self.color) {
        [self.color setFill];
    } else {
        [[UIColor redColor] setFill];
    }
    
    UIRectFill(fillRect);
}

目前得到的效果是一下形式的:

卡拉OK效果-1.gif

因为填充方式不对,这里需要使用另一个函数UIRectFillUsingBlendMode

    // UIRectFill(fillRect);
    UIRectFillUsingBlendMode(colorRect, kCGBlendModeSourceIn);

现在了解到填充方式有两种:直接所有覆盖和有内容显示的位置覆盖。通过UIRectFillUsingBlendMode还可以设置很多种填充方式。

再来一个比较漂亮的UISearchBar

UISearchBar.png 自定义UISearchBar.png

也是比较简单,直接上代码了:

// 初始化方法中用到。initWithCoder:、initWithFrame:
- (void)setup {
    // 设置背景图是为了去掉上下黑线
    self.backgroundImage = [[UIImage alloc] init];
    // 设置SearchBar的颜色主题为白色
    self.barTintColor = [UIColor whiteColor];
    // 修正光标颜色
    self.tintColor = [UIColor colorWithRGB:Color_Green_V];
    // 设置搜索Icon
    [self setImage:[UIImage imageNamed:@"Search_Icon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    // 设置圆角和边框颜色
    UITextField *searchField = [self valueForKey:@"searchField"];
    if (searchField) {
        [searchField setBackgroundColor:[UIColor whiteColor]];
        searchField.font = [UIFont systemFontOfSize:Font_Normal];
        searchField.layer.cornerRadius = searchField.height * 0.5;
        searchField.layer.borderColor = [UIColor colorWithRGB:Color_Green_V].CGColor;
        searchField.layer.borderWidth = 1;
        searchField.layer.masksToBounds = YES;
    }
}

现在我们开始实现一下今天的目标效果

颜色与文字的完美设计1.png

在此之前要用到渐变效果


渐变效果.png
    UIView *backView = [UIView new];
    backView.frame = CGRectMake(0, -20, ScreenW, 64);
    CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init];
    gradientLayer.frame = CGRectMake(0, 0, ScreenW, 64);
    gradientLayer.colors = @[(__bridge id)[UIColor colorWithHex:0xe8292a alpha:0.76].CGColor,(__bridge id)[UIColor colorWithHex:0x60d653 alpha:0.28].CGColor];
    gradientLayer.startPoint = CGPointMake(0, 0);
    gradientLayer.endPoint = CGPointMake(0, 1.0);
    [backView.layer addSublayer:gradientLayer];

虽然知道要用到渐变,但是怎么实现目标效果中指定路径还有文字的颜色渐变呢?
1、创建一个label,并设置layer.cornerRadiuslayer.borderColorlayer.borderWidth
2、大家应该都知道CALayer中有个mask属性,并且他也是一个CALayer对象。那么我们是否可以通过上边的label的layer设置成一个layer的mask呢?而渐变图层CAGradientLayer继承自CALayer,当然也有mask属性,如果它的mask赋值为label.layer是不是能实现我们想要的效果了?开始行动,试一哈

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(30, 130, 250, 50)];
    view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:view];
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 200, 30)];
    label.text = @"哈哈哈哈哈哈哈哈";
    label.textAlignment = NSTextAlignmentCenter;
//    label.textColor = [UIColor clearColor];
    
    label.layer.cornerRadius = 15;
    label.layer.borderColor = [UIColor blackColor].CGColor;
    label.layer.borderWidth = 1;
    
    [view addSubview:label];
    
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = label.frame;
    
    gradientLayer.colors = @[(__bridge id)[UIColor colorWithHex:0xe8292a alpha:0.76].CGColor,(__bridge id)[UIColor colorWithHex:0x60d653 alpha:0.28].CGColor];
    gradientLayer.startPoint = CGPointMake(0, 0);
    gradientLayer.endPoint = CGPointMake(1.0, 1.0);
    
    [view.layer addSublayer:gradientLayer];
    gradientLayer.mask = label.layer;
    
    // 父层改了,坐标系需要重新设置
    label.frame = gradientLayer.bounds;

呵呵,很高兴就这么完成了。
上边代码需要注意和了解的是:
1,mask图层,根据透明度进行裁剪,只保留非透明部分,显示底部内容。所以label的文字颜色与边框颜色不能为空。
2,因为label的layer设置为别的图层的mask时,frame机制改变了,所以坐标系需要重新设置。

另外可能还想让这个渐变的颜色一直变化,还可以加一个定时器。

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5 repeats:YES block:^(NSTimer * _Nonnull timer) {
        gradientLayer.colors = @[(__bridge id)[UIColor randomColor].CGColor, (__bridge id)[UIColor randomColor].CGColor,(__bridge id)[UIColor randomColor].CGColor];
    }];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
图层与文字的完美设计2.gif

现在我们将上边的label,换成button,希望点击文字时有响应。代码就不写了,结果是没有任何响应。Debug view hierarchy之后,发现button控件是不存在的。回到以前的代码,发现label也同样是不存在的。
注意:一旦把控件层设置为mask层,控件层就不能显示了,会直接从父层中移除,然后作为渐变层的mask层,且控件层的父层会指向渐变层。
那么怎么让其有点击事件呢?将上边代码的父控件view的类型改为UIButton即可。😂😂😂

上一篇下一篇

猜你喜欢

热点阅读