在項目需求中往往有這樣一種場景,需要做半透明的視圖,一般的情形可能會想到做一個中間層的view,設置它的透明度,這樣就可以達到這種效果,但從了解了用貝塞爾曲線畫出來之后,就覺得用view去實現有些Low了,這里就簡單介紹如何用貝塞爾曲線去畫半透明圖片
1.畫半透明的矩形
- (UIImage *)getOpaueImage {
UIImage *opaueImage;
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale);
//獲得當前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//創建貝塞爾曲線
UIBezierPath *path = [UIBezierPath bezierPath];
//設置矩形繪圖路徑
[path moveToPoint:CGPointMake(0, 0)];
[path addLineToPoint:CGPointMake(self.frame.size.width, 0)];
[path addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height)];
[path addLineToPoint:CGPointMake(0, self.frame.size.height)];
[path addLineToPoint:CGPointMake(0, 0)];
//繪制
CGContextAddPath(ctx, path.CGPath);
//設置填充顏色
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.8] setFill];
CGContextFillPath(ctx);
//獲取畫的圖片
opaueImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return opaueImage;
}
//這里主要的是貝塞爾曲線路徑的設置
繪制步驟不難,下面再介紹一種帶圓角的矩形,至于圓角設置,看具體需求,這里以右側半圓弧為例
2.繪制帶弧度的矩形圖片
- (UIImage *)getRectWithCorner {
UIImage *opaueImage;
UIGraphicsBeginImageContextWithOptions(self.frame.size,NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 0)];
[path addLineToPoint:CGPointMake(self.frame.size.width - self.frame.size.height / 2, 0)];
//添加弧度
[path addArcWithCenter:CGPointMake(self.frame.size.width - self.frame.size.height / 2, self.frame.size.height / 2) radius:self.frame.size.height / 2 startAngle:3 * M_PI / 2 endAngle:5 * M_PI / 2 clockwise:YES];
[path addLineToPoint:CGPointMake(0, self.frame.size.height)];
[path addLineToPoint:CGPointMake(0, 0)];
CGContextAddPath(context, path.CGPath);
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5] setFill];
CGContextFillPath(context);
opaueImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return opaueImage;
}
實現起來其實很簡單,主要的就是路徑的設置
3.學習了上面兩種之后,在項目需求里有一種視圖是左邊是選中和非選中狀態的圓環,右邊是數字,第一感覺是可以用button,左邊放圖片右邊放數字,這樣也是可以的,其實用貝塞爾曲線也是可以實現的,具體步驟如下
.h中
#import <UIKit/UIKit.h>
@interface WNSelectedButton : UIButton
@property (nonatomic,copy) NSString *title;
@end
.m中
#import "WNSelectedButton.h"
@implementation WNSelectedButton
- (void)setTitle:(NSString *)title {
_title = title;
[self setNeedsDisplay];//重新繪制
}
//進行繪制
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
if (self.selected) {
UIImage *selectedImage = [self selectedImage];
[selectedImage drawInRect:rect];
}else {
UIImage *normalImage = [self normalImage];
[normalImage drawInRect:rect];
}
UIFont *font = [UIFont systemFontOfSize:ScaleToScreenW(12)];
CGSize size = [self.title sizeWithAttributes:@{NSFontAttributeName:font}];
[self.title drawInRect:CGRectMake(20,rect.size.height * 0.5 - size.height / 2, rect.size.width - 20, rect.size.height) withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName:[UIColor whiteColor]}];
}
//正常狀態下的圖片
- (UIImage *)normalImage {
UIImage *normalImage;
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale);
CGContextRef ctx = UIGraphicsGetCurrentContext();
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(6, self.frame.size.height * 0.5) radius:5 startAngle:0 endAngle:2 * M_PI clockwise:YES];
CGContextAddPath(ctx, circlePath.CGPath);
[[UIColor whiteColor] setStroke];
CGContextSetLineWidth(ctx, 1.0);
CGContextStrokePath(ctx);
normalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return normalImage;
}
//選中狀態下的圖片
- (UIImage *)selectedImage {
UIImage *selectedImage;
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale);
CGContextRef ctx = UIGraphicsGetCurrentContext();
//先畫外圓
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(6, self.frame.size.height * 0.5) radius:5 startAngle:0 endAngle:2 * M_PI clockwise:YES];
CGContextAddPath(ctx, circlePath.CGPath);
[[UIColor colorFromHexRGB:@"#da4a4a"] setStroke];
CGContextSetLineWidth(ctx, 1.0);
CGContextStrokePath(ctx);
//再畫內圓
UIBezierPath *centerPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(6, self.frame.size.height * 0.5) radius:2 startAngle:0 endAngle:2 * M_PI clockwise:YES];
CGContextAddPath(ctx, centerPath.CGPath);
[[UIColor colorFromHexRGB:@"#da4a4a"] setFill];
CGContextFillPath(ctx);
selectedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return selectedImage;
}
@end
其實也不難理解,自己嘗試幾次就可以掌握其中的關竅,這是貝塞爾曲線結合CG框架實現的,在tableView的cell中如果有相關圓角或者圓形圖片的處理,都可以考慮這種實現方式,可以極大地優化tableView的卡頓問題