动态实时设置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值