动态实时设置CAShapeLayer贝塞尔曲线的坐标点
效果图:
源码:
PathDirectionView.h 与 PathDirectionView.m
// // PathDirectionView.h // Path // // Created by XianMingYou on 15/2/27. // Copyright (c) 2015年 XianMingYou. All rights reserved. // #import <UIKit/UIKit.h> #import "UIView+SetRect.h" @interface PathDirectionView : UIView /** * 起始点在右边 */ @property (nonatomic) BOOL startPointAtRight; /** * 根据百分比显示 * * @param percent 百分比 */ - (void)showPercent:(CGFloat)percent; @end
// // PathDirectionView.m // Path // // Created by XianMingYou on 15/2/27. // Copyright (c) 2015年 XianMingYou. All rights reserved. // #import "PathDirectionView.h" @interface PathDirectionView () { CAShapeLayer *_shapeLayer; } @end @implementation PathDirectionView /** * 修改当前view的backupLayer为CAGradientLayer * * @return CAGradientLayer类名字 */ + (Class)layerClass { return [CAShapeLayer class]; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { _shapeLayer = (CAShapeLayer *)self.layer; _shapeLayer.fillColor = [[UIColor clearColor] CGColor]; _shapeLayer.strokeColor = [[UIColor redColor] CGColor]; _shapeLayer.lineWidth = 1.f; _shapeLayer.strokeEnd = 0.f; _shapeLayer.opacity = 0.f; _shapeLayer.path = [self createPathWithHeight:0]; } return self; } /** * 创建出贝塞尔曲线 * * @param height 高度 * * @return 贝塞尔曲线 */ - (CGPathRef)createPathWithHeight:(CGFloat)height { UIBezierPath *bezierPath = UIBezierPath.bezierPath; CGPoint startPoint = CGPointZero; CGPoint endPoint = CGPointZero; if (self.startPointAtRight == NO) { startPoint = CGPointMake(self.width, height); endPoint = CGPointZero; } else { startPoint = CGPointMake(0, height); endPoint = CGPointMake(self.width, 0); } [bezierPath moveToPoint:startPoint]; [bezierPath addLineToPoint:endPoint]; return bezierPath.CGPath; } - (void)showPercent:(CGFloat)percent { if (percent < 0) { _shapeLayer.path = [self createPathWithHeight:0]; _shapeLayer.strokeEnd = 0; _shapeLayer.opacity = 0; } else if (percent >= 0 && percent <= 0.5f) { // [0, 0.5] _shapeLayer.path = [self createPathWithHeight:0]; _shapeLayer.strokeEnd = percent * 2.f; _shapeLayer.opacity = percent * 2.f; } else if (percent <= 1.f) { // (0.5, 1] CGFloat currentPercent = percent - 0.5f; _shapeLayer.path = [self createPathWithHeight:currentPercent * self.height * 2]; _shapeLayer.strokeEnd = 1.f; _shapeLayer.opacity = 1.f; } else { // (1, +无穷大) _shapeLayer.path = [self createPathWithHeight:self.height]; _shapeLayer.strokeEnd = 1.f; _shapeLayer.opacity = 1.f; } } @end
ShowDownView.h 与 ShowDownView.m
// // ShowDownView.h // Path // // Created by XianMingYou on 15/2/27. // Copyright (c) 2015年 XianMingYou. All rights reserved. // #import <UIKit/UIKit.h> #import "PathDirectionView.h" @interface ShowDownView : UIView - (void)showPercent:(CGFloat)percent; @end
// // ShowDownView.m // Path // // Created by XianMingYou on 15/2/27. // Copyright (c) 2015年 XianMingYou. All rights reserved. // #import "ShowDownView.h" @interface ShowDownView () @property (nonatomic, strong) PathDirectionView *leftView; @property (nonatomic, strong) PathDirectionView *rightView; @end @implementation ShowDownView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { CGFloat width = frame.size.width / 2.f; CGFloat height = frame.size.height; CGRect leftRect = CGRectMake(0, 0, width, height); CGRect rightRect = CGRectMake(width, 0, width, height); self.leftView = [[PathDirectionView alloc] initWithFrame:leftRect]; self.rightView = [[PathDirectionView alloc] initWithFrame:rightRect]; self.rightView.startPointAtRight = YES; [self addSubview:self.leftView]; [self addSubview:self.rightView]; } return self; } - (void)showPercent:(CGFloat)percent { [self.leftView showPercent:percent]; [self.rightView showPercent:percent]; } @end
核心原理:
1. 即时的根据值的变化重新生成path值并赋值给CAShapeLayer
2. 即时的根据值得变化设定strokeEnd值