一.iOS貝塞爾曲線與CAShapeLayer詳解

實現(xiàn)效果圖如下:


實現(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ù)更新中...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末馁菜,一起剝皮案震驚了整個濱河市茴扁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌汪疮,老刑警劉巖峭火,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毁习,死亡現(xiàn)場離奇詭異,居然都是意外死亡卖丸,警方通過查閱死者的電腦和手機纺且,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稍浆,“玉大人载碌,你說我怎么就攤上這事⌒品悖” “怎么了嫁艇?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弦撩。 經(jīng)常有香客問我步咪,道長,這世上最難降的妖魔是什么孤钦? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任歧斟,我火速辦了婚禮,結(jié)果婚禮上偏形,老公的妹妹穿的比我還像新娘静袖。我一直安慰自己,他們只是感情好俊扭,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布队橙。 她就那樣靜靜地躺著,像睡著了一般萨惑。 火紅的嫁衣襯著肌膚如雪捐康。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天庸蔼,我揣著相機與錄音解总,去河邊找鬼。 笑死姐仅,一個胖子當著我的面吹牛花枫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掏膏,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼劳翰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了馒疹?” 一聲冷哼從身側(cè)響起佳簸,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颖变,沒想到半個月后生均,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體听想,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年疯特,在試婚紗的時候發(fā)現(xiàn)自己被綠了哗魂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡漓雅,死狀恐怖录别,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情邻吞,我是刑警寧澤组题,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站抱冷,受9級特大地震影響崔列,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜旺遮,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一赵讯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧耿眉,春花似錦边翼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至筐骇,卻和暖如春债鸡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铛纬。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工厌均, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人告唆。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓莫秆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悔详。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容