
我們先來一個簡單的卡拉OK效果練練手吧

這個非常容易,設(shè)置定時器計算進(jìn)度progress。重寫UILabel的drawRect:,通過progress計算顏色區(qū)域,然后填充顏色就行,不過要注意一下填充方式。
// 這里計算字體大小與frame需要做一些優(yōu)化。因為該方式調(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);
}
目前得到的效果是一下形式的:

因為填充方式不對,這里需要使用另一個函數(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)在我們開始實現(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];
雖然知道要用到漸變,但是怎么實現(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是不是能實現(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,因為label的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,希望點擊文字時有響應(yīng)。代碼就不寫了,結(jié)果是沒有任何響應(yīng)。Debug view hierarchy之后,發(fā)現(xiàn)button控件是不存在的?;氐揭郧暗拇a,發(fā)現(xiàn)label也同樣是不存在的。
注意:一旦把控件層設(shè)置為mask層,控件層就不能顯示了,會直接從父層中移除,然后作為漸變層的mask層,且控件層的父層會指向漸變層。
那么怎么讓其有點擊事件呢?將上邊代碼的父控件view的類型改為UIButton即可。??????