我們先來一個簡單的卡拉OK效果練練手吧
這個非常容易盯滚,設(shè)置定時器計(jì)算進(jìn)度progress序矩。重寫UILabel的drawRect:
秧均,通過progress計(jì)算顏色區(qū)域锉罐,然后填充顏色就行能耻,不過要注意一下填充方式赏枚。
// 這里計(jì)算字體大小與frame需要做一些優(yōu)化。因?yàn)樵摲绞秸{(diào)用非常多
- (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);
}
目前得到的效果是一下形式的:
因?yàn)樘畛浞绞讲粚ο停@里需要使用另一個函數(shù)UIRectFillUsingBlendMode
:
// UIRectFill(fillRect);
UIRectFillUsingBlendMode(colorRect, kCGBlendModeSourceIn);
現(xiàn)在了解到填充方式有兩種:直接所有覆蓋和有內(nèi)容顯示的位置覆蓋饿幅。通過UIRectFillUsingBlendMode
還可以設(shè)置很多種填充方式谤绳。
再來一個比較漂亮的UISearchBar
也是比較簡單捅彻,直接上代碼了:
// 初始化方法中用到。initWithCoder:挨下、initWithFrame:
- (void)setup {
// 設(shè)置背景圖是為了去掉上下黑線
self.backgroundImage = [[UIImage alloc] init];
// 設(shè)置SearchBar的顏色主題為白色
self.barTintColor = [UIColor whiteColor];
// 修正光標(biāo)顏色
self.tintColor = [UIColor colorWithRGB:Color_Green_V];
// 設(shè)置搜索Icon
[self setImage:[UIImage imageNamed:@"Search_Icon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
}
- (void)layoutSubviews {
[super layoutSubviews];
// 設(shè)置圓角和邊框顏色
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;
}
}
現(xiàn)在我們開始實(shí)現(xiàn)一下今天的目標(biāo)效果
在此之前要用到漸變效果
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];
雖然知道要用到漸變洪燥,但是怎么實(shí)現(xiàn)目標(biāo)效果中指定路徑還有文字的顏色漸變呢磕秤?
1、創(chuàng)建一個label捧韵,并設(shè)置layer.cornerRadius
市咆、layer.borderColor
與layer.borderWidth
。
2再来、大家應(yīng)該都知道CALayer中有個mask屬性蒙兰,并且他也是一個CALayer對象。那么我們是否可以通過上邊的label的layer設(shè)置成一個layer的mask呢芒篷?而漸變圖層CAGradientLayer繼承自CALayer搜变,當(dāng)然也有mask屬性,如果它的mask賦值為label.layer是不是能實(shí)現(xiàn)我們想要的效果了梭伐?開始行動痹雅,試一哈
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;
// 父層改了,坐標(biāo)系需要重新設(shè)置
label.frame = gradientLayer.bounds;
呵呵糊识,很高興就這么完成了绩社。
上邊代碼需要注意和了解的是:
1,mask圖層赂苗,根據(jù)透明度進(jìn)行裁剪愉耙,只保留非透明部分,顯示底部內(nèi)容拌滋。所以label的文字顏色與邊框顏色不能為空朴沿。
2,因?yàn)閘abel的layer設(shè)置為別的圖層的mask時,frame機(jī)制改變了赌渣,所以坐標(biāo)系需要重新設(shè)置魏铅。
另外可能還想讓這個漸變的顏色一直變化,還可以加一個定時器坚芜。
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];
現(xiàn)在我們將上邊的label览芳,換成button,希望點(diǎn)擊文字時有響應(yīng)鸿竖。代碼就不寫了沧竟,結(jié)果是沒有任何響應(yīng)。Debug view hierarchy之后缚忧,發(fā)現(xiàn)button控件是不存在的悟泵。回到以前的代碼闪水,發(fā)現(xiàn)label也同樣是不存在的糕非。
注意:一旦把控件層設(shè)置為mask層,控件層就不能顯示了,會直接從父層中移除敦第,然后作為漸變層的mask層峰弹,且控件層的父層會指向漸變層。
那么怎么讓其有點(diǎn)擊事件呢芜果?將上邊代碼的父控件view的類型改為UIButton即可鞠呈。??????