實現(xiàn)效果圖如下:
一.創(chuàng)建一個貝塞爾曲線
1.基礎方法,先創(chuàng)建UIBezierPath對象,在添加路徑
+ (instancetype)bezierPath;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
+(instancetype)new;
這三個方法都可以得到一個UIBezierPath對象
然后通過一下方法添加路徑
- (void)moveToPoint:(CGPoint)point;//移動到某一起點,這比第一步必須要有
- (void)addLineToPoint:(CGPoint)point;//添加一條直線從起點到設定的某點
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;//添加一條曲線在起點和設置的重點之前,通過兩個控制點控制曲線形狀
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;//添加一條曲線在起點和設置的重點之前,通過一個控制點控制曲線形狀
- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwiseNS_AVAILABLE_IOS(4_0);//添加弧線有某點為弧心,可設置半徑以及起始和結(jié)束角度,順逆時針方向
- (void)closePath;//使路徑封閉
2.類方法直接創(chuàng)建指定路徑
+ (instancetype)bezierPathWithRect:(CGRect)rect;//創(chuàng)建一個在一定范圍內(nèi)封閉邊沿路徑
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;//在一定范圍內(nèi)封閉的最大的圓形路徑
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;// rounds all corners with the same horizontal and vertical radius;//在一定范圍內(nèi)以一個指定半徑的封閉圓形路徑
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;//在一定范圍內(nèi)指定一個或多個角切圓角并指定圓角半徑的封閉路徑
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;//以某點為中心一個半徑為多少,起始角度與結(jié)束角度的弧形不封閉區(qū)域,可指定順時針和逆時針YES表示順,可通過- (void)closePath;方法封閉路徑
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;//指定某個繪制路徑為路徑的路徑
二.CAShapeLayer屬性
@property(nullable) CGPathRef path;
定義要呈現(xiàn)的形狀的路徑泄私。如果路徑延伸在圖層邊界之外它不會自動被剪切挣跋,只有在誰知clibToBounds的時候才會裁剪赌躺。默認為空⊥裆蹋可以做成動畫物喷。(注意劲够,盡管路徑屬性是可動畫的,但沒有隱式動畫)
@property(nullable) CGColorRef strokeColor;
填充路徑的顏色尖奔,或無填充為nil。默認為不透明的黑色穷当√嶙拢可以做成動畫
@property(copy) NSString *lineCap;
填充路徑時使用的填充規(guī)則。
CA_EXTERN NSString *const kCALineCapButt(路徑未封閉端為平的并與區(qū)域齊平)
CA_EXTERN NSString *const kCALineCapRound(路徑未封閉端為圓角的并超出區(qū)域一部分)
CA_EXTERN NSString *const kCALineCapSquare(路徑未封閉端為平的并超出區(qū)域一部分)
以上超出部分為lineWidth屬性的一半
@property CGFloat lineWidth;
路徑寬度
@property CGFloat strokeStart;
@property CGFloat strokeEnd;
路徑后開始和結(jié)束,值都在0~1之間,可以做動畫
@property(nullable) CGColorRef fillColor;
@property(copy) NSString *fillRule;
區(qū)域顏色,樣式
三.附上自己寫的一個效果測試兩者結(jié)合做的簡單動畫
測試代碼如下:(直接創(chuàng)建一個工程在mainstoryboard創(chuàng)建一個按鈕,替換掉.m,加上點擊事件可看效果)
////? ViewController.m//? HudTest////? Created by iOS on 17/6/8.//? Copyright ? 2017年 iOS. All rights reserved.//
#import "ViewController.h"
@interface ViewController (){
CAShapeLayer *maskLayer;
CABasicAnimation *_animation;
}
@end
@implementation ViewController
- (IBAction)show:(id)sender {
//只點一次看看效果就好,想自己怎么做都好,我比較懶就不做清除判斷了
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:80 startAngle:0 endAngle:M_PI clockwise:YES];
maskLayer = [CAShapeLayer layer];
maskLayer.backgroundColor = [UIColor clearColor].CGColor;
maskLayer.path = bezierPath.CGPath;
maskLayer.strokeColor = [UIColor greenColor].CGColor;
maskLayer.fillColor = [UIColor whiteColor].CGColor;
maskLayer.lineWidth = 20;
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.lineCap = kCALineCapRound;
[self.view.layer addSublayer:maskLayer];
maskLayer.strokeStart = 0;
maskLayer.strokeEnd = 1;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue = @0;
animation.duration = 3.0f;
animation.delegate = self;
animation.repeatCount = 0;
[animation setValue:@"BasicAnimationEnd" forKey:@"animationName"];
[maskLayer addAnimation:animation forKey:@"BasicAnimationEnd"];
}
- (void)animationDidStart:(CAAnimation *)anim{
if (_animation) {
UIBezierPath *bezierPath1 = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:30 startAngle:M_PI endAngle:0 clockwise:NO];
maskLayer = [CAShapeLayer layer];
maskLayer.backgroundColor = [UIColor clearColor].CGColor;
maskLayer.path = bezierPath1.CGPath;
maskLayer.strokeColor = [UIColor redColor].CGColor;
maskLayer.fillColor = [UIColor whiteColor].CGColor;
maskLayer.lineWidth = 15;
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.lineCap = kCALineCapRound;
[self.view.layer addSublayer:maskLayer];
maskLayer.strokeStart = 0;
maskLayer.strokeEnd = 1;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue = @0;
animation.duration = 0.8f;
animation.repeatCount = 0;
[animation setValue:@"BasicAnimationEnd" forKey:@"animationName"];
[maskLayer addAnimation:animation forKey:@"BasicAnimationEnd"];
}else{
UIBezierPath *bezierPath1 = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:60 startAngle:M_PI endAngle:0 clockwise:NO];
maskLayer = [CAShapeLayer layer];
maskLayer.backgroundColor = [UIColor clearColor].CGColor;
maskLayer.path = bezierPath1.CGPath;
maskLayer.strokeColor = [UIColor yellowColor].CGColor;
maskLayer.fillColor = [UIColor whiteColor].CGColor;
maskLayer.lineWidth = 20;
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.lineCap = kCALineCapRound;
[self.view.layer addSublayer:maskLayer];
maskLayer.strokeStart = 0;
maskLayer.strokeEnd = 1;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue = @0;
animation.duration = 2.0f;
animation.repeatCount = 0;
[animation setValue:@"BasicAnimationEnd" forKey:@"animationName"];
[maskLayer addAnimation:animation forKey:@"BasicAnimationEnd"];
}}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
if (!_animation) {
UIBezierPath *bezierPath2 = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:45 startAngle:0 endAngle:M_PI clockwise:YES];
maskLayer = [CAShapeLayer layer];
maskLayer.backgroundColor = [UIColor clearColor].CGColor;
maskLayer.path = bezierPath2.CGPath;
maskLayer.strokeColor = [UIColor orangeColor].CGColor;
maskLayer.fillColor = [UIColor whiteColor].CGColor;
maskLayer.lineWidth = 15;
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.lineCap = kCALineCapRound;
[self.view.layer addSublayer:maskLayer];
maskLayer.strokeStart = 0;
maskLayer.strokeEnd = 1;
_animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
_animation.fromValue = @0;
_animation.delegate = self;
_animation.duration = 1.0f;
[_animation setValue:@"BasicAnimationEnd" forKey:@"animationName"];
[maskLayer addAnimation:_animation forKey:@"BasicAnimationEnd"];
}
}
@end
Copyright ? 2017年ZaneWangWang. All rights reserved.
持續(xù)更新中...