[控件] 画饼状图的控件
控件 状图
2023-09-14 08:57:16 时间
画饼状图的控件
效果
注意:支持遮罩效果
源码
https://github.com/YouXianMing/UI-Component-Collection
// // CircleView.h // YXMWeather // Created by XianMingYou on 15/5/12. // Copyright (c) 2015年 XianMingYou. All rights reserved. #import UIKit/UIKit.h @interface CircleView : UIView * 线条宽度 @property (nonatomic) CGFloat lineWidth; * 线条颜色 @property (nonatomic, strong) UIColor *lineColor; * 旋转方向 @property (nonatomic) BOOL clockWise; * 开始角度 @property (nonatomic) CGFloat startAngle; * 初始化view - (void)buildView; * 做strokeEnd动画 * @param value 取值 [0, 1] * @param animated 是否执行动画 * @param duration 动画持续的时间 - (void)strokeEnd:(CGFloat)value animated:(BOOL)animated duration:(CGFloat)duration; * 做strokeStart动画 * @param value 取值 [0, 1] * @param animated 是否执行动画 * @param duration 动画持续的时间 - (void)strokeStart:(CGFloat)value animated:(BOOL)animated duration:(CGFloat)duration; * 便利构造器创建出实例对象 * @param frame frame值 * @param width 线条宽度 * @param color 线条颜色 * @param clockWise 是否是顺时钟 * @param angle 开始是否的角度(取值范围 0° ~ 360°) * @return 实例对象 + (instancetype)circleViewWithFrame:(CGRect)frame lineWidth:(CGFloat)width lineColor:(UIColor *)color clockWise:(BOOL)clockWise startAngle:(CGFloat)angle; @end
// // CircleView.m // YXMWeather // Created by XianMingYou on 15/5/12. // Copyright (c) 2015年 XianMingYou. All rights reserved. #import "CircleView.h" #import "YXEasing.h" // 将度数转换为弧度 #define RADIAN(degrees) ((M_PI * (degrees))/ 180.f) // 将弧度转换为度数 #define DEGREES(radian) ((radian) * 180.f / M_PI) @interface CircleView () @property (nonatomic, strong) CAShapeLayer *circleLayer; // 圆形layer @implementation CircleView * 初始化frame值 * @param frame 尺寸值 * @return 实例对象 - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // 创建出layer [self createCircleLayer]; return self; * 创建出layer - (void)createCircleLayer { self.circleLayer = [CAShapeLayer layer]; self.circleLayer.frame = self.bounds; [self.layer addSublayer:self.circleLayer]; * 初始化view - (void)buildView { // 初始化信息 CGFloat lineWidth = (self.lineWidth = 0 ? 1 : self.lineWidth); UIColor *lineColor = (self.lineColor == nil ? [UIColor blackColor] : self.lineColor); CGSize size = self.bounds.size; CGFloat radius = size.width / 2.f - lineWidth / 2.f; // 设置半径(刚好贴到frame上面去) // 旋转方向 BOOL clockWise = self.clockWise; CGFloat startAngle = 0; CGFloat endAngle = 0; if (clockWise == YES) { startAngle = -RADIAN(180 - self.startAngle); endAngle = RADIAN(180 + self.startAngle); } else { startAngle = RADIAN(180 - self.startAngle); endAngle = -RADIAN(180 + self.startAngle); // 创建出贝塞尔曲线 UIBezierPath *circlePath \ = [UIBezierPath bezierPathWithArcCenter:CGPointMake(size.height / 2.f, size.width / 2.f) radius:radius startAngle:startAngle endAngle:endAngle clockwise:clockWise]; // 获取path self.circleLayer.path = circlePath.CGPath; // 设置颜色 self.circleLayer.strokeColor = lineColor.CGColor; self.circleLayer.fillColor = [[UIColor clearColor] CGColor]; self.circleLayer.lineWidth = lineWidth; self.circleLayer.strokeEnd = 0.f; - (void)strokeEnd:(CGFloat)value animated:(BOOL)animated duration:(CGFloat)duration { // 过滤掉不合理的值 if (value = 0) { value = 0; } else if (value = 1) { value = 1.f; if (animated) { // 关键帧动画 CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animation]; keyAnimation.keyPath = @"strokeEnd"; keyAnimation.duration = duration; keyAnimation.values = \ [YXEasing calculateFrameFromValue:self.circleLayer.strokeEnd toValue:value func:CubicEaseInOut frameCount:duration * 60]; // 执行动画 self.circleLayer.strokeEnd = value; [self.circleLayer addAnimation:keyAnimation forKey:nil]; } else { // 关闭动画 [CATransaction setDisableActions:YES]; self.circleLayer.strokeEnd = value; [CATransaction setDisableActions:NO]; - (void)strokeStart:(CGFloat)value animated:(BOOL)animated duration:(CGFloat)duration { // 过滤掉不合理的值 if (value = 0) { value = 0; } else if (value = 1) { value = 1.f; if (animated) { // 关键帧动画 CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animation]; keyAnimation.keyPath = @"strokeStart"; keyAnimation.duration = duration; keyAnimation.values = \ [YXEasing calculateFrameFromValue:self.circleLayer.strokeStart toValue:value func:CubicEaseInOut frameCount:duration * 60]; // 执行动画 self.circleLayer.strokeStart = value; [self.circleLayer addAnimation:keyAnimation forKey:nil]; } else { // 关闭动画 [CATransaction setDisableActions:YES]; self.circleLayer.strokeStart = value; [CATransaction setDisableActions:NO];
CircleView *circleView = [[CircleView alloc] initWithFrame:frame]; circleView.lineWidth = width; circleView.lineColor = color; circleView.clockWise = clockWise; circleView.startAngle = angle; return circleView; @end
细节
以上是几个核心的参数
相关文章
- elementui树形控件_elementui树形控件筛选
- requiredargsconstructor_gridview控件的事件有哪些
- Vue学习笔记之moment.js日期处理控件
- android控件大全及用法_学双人舞一步一步教学
- 开发Linux下支付宝控件开发实践(linux支付宝控件)
- JavaScript监测ActiveX控件是否已经安装过的代码
- asp.net中将数据库绑定到DataList控件的实现方法与实例代码
- ASP.NET2.0中用Gridview控件操作数据的代码
- asp.net中使用自定义控件的方式实现一个分页控件的代码
- Android控件(button)对齐方法实现详解
- 给Repeater控件里添加序号的5种才常见方法介绍
- JavaScript实现的日期控件具体代码
- js之ActiveX控件使用说明newActiveXObject()
- ASP.NET中repeater控件用法实例