IOS 圆形进度条
//
// CCProgressView.h
// Demo
//
// Created by leao on 2017/8/7.
// Copyright © 2017年 zaodao. All rights reserved.
// #import <UIKit/UIKit.h> typedef NS_ENUM(NSInteger, CCProgressViewStyle) {
CCProgressViewStyleCircle, // 圆形进度条
CCProgressViewStyleBar, // 条形进度条
CCProgressViewStyleDefault = CCProgressViewStyleCircle,
}; @interface CCProgressView : UIView
@property(nonatomic, assign, setter=setProgress:) CGFloat progress; // 0.0 ~ 1.0 @property(nonatomic, assign) CCProgressViewStyle progressViewStyle; // 进度条style
@property(nonatomic, strong) UIColor *trackTintColor; // 进度条背景色
@property(nonatomic, strong) UIColor *progressTintColor; // 进度条颜色
@property(nonatomic, strong) UIColor *progressFullTintColor; // 进度完成时progressTint的颜色
@property(nonatomic, assign) CGFloat lineWidth; // 绘制progress宽度 default: 10
@property(nonatomic, assign) CGFloat trackerWidth; // 绘制progress宽度 default: 10 // CCProgressViewStyleCircle 有效
@property(nonatomic, strong) UIColor *fillColor; // 中心颜色
@property(nonatomic, assign) BOOL clockwise; // 是否是顺时针 default: YES
@property(nonatomic, assign) CGFloat startAngle; // 进度条开始angle, default: -M_PI/2.0
@property (nonatomic, strong) UIButton *centerBtn; // 记录进度的Label
@property (nonatomic, strong) UIColor *labelbackgroundColor; // Label的背景色 默认clearColor
@property (nonatomic, strong) UIColor *textColor; // Label的字体颜色 默认黑色
@property (nonatomic, strong) UIFont *textFont; // Label的字体大小 默认15 - (void)setProgress:(CGFloat)progress;
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated;
@end
//
// CCProgressView.m
// Demo
//
// Created by leao on 2017/8/7.
// Copyright © 2017年 zaodao. All rights reserved.
// #import "CCProgressView.h"
#import <pop/POP.h>
#import <objc/runtime.h>
#import <ReactiveCocoa/ReactiveCocoa.h> #define kCCProgressFillColor [UIColor clearColor]
#define kCCProgressTintColor RGBCOLOR(214, 88, 45)
#define kCCTrackTintColor RGBCOLOR(243, 212, 187)
#define PROGRESS_WIDTH self.frame.size.width
#define PROGRESS_HEIGHT self.frame.size.height #define kAnimTimeInterval 2 @interface CCProgressView () @property(nonatomic, strong) CAShapeLayer *trackLayer;
@property(nonatomic, strong) CAShapeLayer *progressLayer; @end
@implementation CCProgressView - (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
} - (instancetype)init
{
self = [super init];
if (self) {
[self initSubviews];
}
return self;
} #pragma mark - private
- (void)initSubviews
{
_progressViewStyle = CCProgressViewStyleDefault;
_progressTintColor = kCCProgressTintColor;
_trackTintColor = kCCTrackTintColor;
_lineWidth = ;
_trackerWidth = ; _fillColor = kCCProgressFillColor;
_clockwise = YES;
_startAngle = - M_PI / 2.0; self.backgroundColor = [UIColor clearColor]; self.trackLayer = [CAShapeLayer layer];
self.trackLayer.lineCap = kCALineCapButt;
self.trackLayer.lineJoin = kCALineCapButt;
self.trackLayer.lineWidth = _lineWidth;
self.trackLayer.fillColor = nil;
self.trackLayer.strokeColor = _trackTintColor.CGColor;
self.trackLayer.frame = self.bounds;
[self.layer addSublayer:self.trackLayer]; self.progressLayer = [CAShapeLayer layer];
self.progressLayer.lineCap = kCALineCapButt;
self.progressLayer.lineJoin = kCALineCapButt;
self.progressLayer.lineWidth = _trackerWidth;
self.progressLayer.fillColor = _fillColor.CGColor;
self.progressLayer.strokeColor = _progressTintColor.CGColor;
self.progressLayer.frame = self.bounds;
[self.layer addSublayer:self.progressLayer]; self.progressLayer.strokeEnd = 0.0; [self addSubview:self.centerBtn];
} - (void)layoutSubviews
{
[super layoutSubviews]; [self updateLayerPath];
} #pragma mark - private - (UIButton *)centerBtn
{
if(!_centerBtn)
{
_centerBtn = [[UIButton alloc] initWithFrame:CGRectMake(, , PROGRESS_WIDTH - , PROGRESS_HEIGHT - )];
_centerBtn.center = CGPointMake(PROGRESS_WIDTH/, PROGRESS_HEIGHT/);
_centerBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
_centerBtn.layer.cornerRadius = _centerBtn.width/;
_centerBtn.backgroundColor = RGBCOLOR(, , );
_centerBtn.titleLabel.adjustsFontSizeToFitWidth = YES;
_centerBtn.userInteractionEnabled = NO;
_centerBtn.layer.masksToBounds = YES;
}
return _centerBtn;
} - (void)updateLayerPath
{
if (_progressViewStyle == CCProgressViewStyleCircle) {
self.trackLayer.frame = self.bounds;
self.progressLayer.frame = self.bounds; CGFloat radius = CGRectGetWidth(self.frame) > CGRectGetHeight(self.frame) ?
(CGRectGetHeight(self.frame) - _lineWidth) / 2.0 : (CGRectGetWidth(self.frame) - _lineWidth) / 2.0;
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:self.progressLayer.position radius:radius startAngle:_startAngle endAngle:_clockwise ? _startAngle + * M_PI : _startAngle - * M_PI clockwise:_clockwise];
self.trackLayer.path = bezierPath.CGPath;
self.progressLayer.path = bezierPath.CGPath;
} else {
self.trackLayer.frame = CGRectMake(, (CGRectGetHeight(self.frame) - _lineWidth) / 2.0, CGRectGetWidth(self.frame), _lineWidth);
self.progressLayer.frame = self.trackLayer.frame; UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:CGPointMake(, self.progressLayer.position.y)];
[bezierPath addLineToPoint:CGPointMake(CGRectGetWidth(self.frame), self.progressLayer.position.y)];
self.trackLayer.path = bezierPath.CGPath;
self.progressLayer.path = bezierPath.CGPath;
}
} #pragma mark - setter
- (void)setTrackTintColor:(UIColor *)trackTintColor
{
_trackTintColor = trackTintColor;
self.trackLayer.strokeColor = trackTintColor.CGColor;
} - (void)setProgressTintColor:(UIColor *)progressTintColor
{
_progressTintColor = progressTintColor;
self.progressLayer.strokeColor = progressTintColor.CGColor;
} - (void)setProgressFullTintColor:(UIColor *)progressFullTintColor
{
_progressFullTintColor = progressFullTintColor;
if (self.progressLayer.strokeEnd >= 1.0) {
self.progressLayer.strokeEnd = 1.0;
self.progressLayer.strokeColor = _progressFullTintColor.CGColor;
}
} - (void)setLineWidth:(CGFloat)lineWidth
{
_lineWidth = lineWidth;
// self.trackLayer.lineWidth = lineWidth;
self.progressLayer.lineWidth = lineWidth;
if (_progressViewStyle != CCProgressViewStyleCircle) {
[self updateLayerPath];
}
} - (void)setTrackerWidth:(CGFloat)trackerWidth {
_trackerWidth = trackerWidth;
self.trackLayer.lineWidth = _trackerWidth;
if (_progressViewStyle != CCProgressViewStyleCircle) {
[self updateLayerPath];
}
} #pragma mark - setter (CCProgressViewStyleCircle)
- (void)setFillColor:(UIColor *)fillColor
{
_fillColor = fillColor;
self.progressLayer.fillColor = fillColor.CGColor;
} - (void)setClockwise:(BOOL)clockwise
{
_clockwise = clockwise;
[self updateLayerPath];
} - (void)setStartAngle:(CGFloat)startAngle
{
_startAngle = startAngle;
[self updateLayerPath];
} - (void)setProgress:(CGFloat)progress
{
[self setProgress:progress animated:NO];
} - (void)setProgress:(CGFloat)progress animated:(BOOL)animated
{
if (animated) { // 这里的动画可以直接使用CABasicAnimation
POPBasicAnimation *basicAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd];
if (basicAnim) {
basicAnim.duration = kAnimTimeInterval;
basicAnim.toValue = @(progress);
} else {
basicAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd];
basicAnim.fromValue = @(self.progressLayer.strokeEnd);
basicAnim.toValue = @(progress);
basicAnim.duration = * kAnimTimeInterval;
basicAnim.removedOnCompletion = YES;
}
@weakify(self);
basicAnim.completionBlock = ^(POPAnimation *anim, BOOL finished) {
@strongify(self);
POPPropertyAnimation *basicAnim = (POPPropertyAnimation *)anim;
self.progressLayer.strokeEnd = [basicAnim.toValue doubleValue];
if (self.progressLayer.strokeEnd >= 1.0 && _progressFullTintColor) {
self.progressLayer.strokeEnd = 1.0;
self.progressLayer.strokeColor = _progressFullTintColor.CGColor;
}
};
[self.progressLayer pop_addAnimation:basicAnim forKey:kPOPShapeLayerStrokeEnd];
} else {
self.progressLayer.strokeEnd = progress;
if (self.progressLayer.strokeEnd >= 1.0 && _progressFullTintColor) {
self.progressLayer.strokeEnd = 1.0;
self.progressLayer.strokeColor = _progressFullTintColor.CGColor;
}
}
} @end
IOS 圆形进度条的更多相关文章
- [iOS]圆形进度条及计时功能
平时用战网安全令的时候很喜欢圆形倒计时的效果,然后简单看了一下Android的圆形进度条,后来又写了一个IOS的.整体界面参照IOS系统的倒计时功能,顺便熟悉了UIPickerView的一些特性的实现 ...
- iOS之UI--Quartz2D的入门应用--重绘下载圆形进度条
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- iOS开发笔记-根据frame大小动态调整fontSize的自适应文本及圆形进度条控件的实现
最近同样是新App,设计稿里出现一种圆形进度条的设计,如下: 想了想,圆形进度条实现起来不难,但是其中显示百分比的文本确需要自适应,虽然可以使用时自己设定文本字体的大小,但是这样显得很麻烦,也很low ...
- 移动端纯CSS3制作圆形进度条所遇到的问题
近日在开发的页面中,需要制作一个动态的圆形进度条,首先想到的是利用两个矩形,宽等于直径的一半,高等于直径,两个矩形利用浮动贴在一起,设置overflow:hidden属性,作为盒子,内部有一个与其宽高 ...
- android 自定义控件——(四)圆形进度条
----------------------------------↓↓圆形进度条(源代码下有属性解释)↓↓---------------------------------------------- ...
- WPF 实现圆形进度条
项目中用到圆形进度条,首先就想到使用 ProgressBar 扩展一个,在园子里找到迷途的小榔头给出的思路和部分代码,自己加以实现. 进度小于60显示红色,大于60则显示绿色.效果如下: 基本思路: ...
- html5 svg 圆形进度条
html5 svg 圆形进度条 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- canvas圆形进度条
通过定义一个canvas标签, new方法传进ID值,和旋转角度值,即可生成圆形进度条 <!DOCTYPE html> <html lang="en"> & ...
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
Android 高手进阶(21) 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明地址:http://blog.csdn.net/xiaanming/article/detail ...
随机推荐
- Network Monitoring in Software-Defined Networking :A Review(综述)
来源:IEEE SYSTEMS JOURNAL 发表时间:2018 类型:综述 主要内容:概述了SDN监控的发展,并从收集信息.预处理.传送信息.分析.和描述五个阶段进行解读,并比较了传统网络和SDN ...
- Hibernate(10)_双向n对1(双向1对n)
1.双向 1-n 与 双向 n-1 是完全相同的两种情形,这里使用双向多对一来演示 双向 1-n 需要在 1 的一端可以访问 n 的一端, 反之依然. 出版社和图书的关系:Publishers--Bo ...
- 对Android中的堆栈的理解(Stack)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Ln_ZooFa/article/details/50337529 堆栈空间分配 栈(操作系统): ...
- .NET Threadpool的一点认识
说到.NET Threadpool我想大家都知道,只是平时比较零散,顾现在整理一下: 一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相 .NET Threadpool ...
- Activity class {com.../com....MainActivity} does not exist.
报错信息如上图所示,解决步骤: 1. 首先是检查这个MainActivity.java是不是真的存在,且包名和路径无误: 2. 如果文件存在,且包名和路径没有问题,那么就打开你项目所在的/androi ...
- 修改Electron的libcc(libchromiumcontent)源码,重新编译electron, 设置event.isTrusted为true
VPN非常注意: 编译的过程需要使用VPN, 否者chromium的源代码无法下载, 后面会出现总总问题 Electron的编译环境, 推荐使用物理机: win10 64位 英文版, 为了避免后期出现 ...
- ionic使用iframe时无法显示网页或报错
ionic使用iframe时无法显示网页或报错 Uncaught DOMException: Blocked a frame with origin 在config.xml中添加 <access ...
- Eclipse和MyEclipse使用技巧--解决MyEclipse中的js报错的小方法
今天,下了个模版,但是导进去的时候发现js会报错.看了下其他都没有错误.而有一个js报错误,请原谅我有点红色强迫症,不能留一点红色 . 错误如下:Syntax error on token " ...
- App安全
经常做的网络参数加密解密,以及防止数据重放之外,还提到了防范反编译的风险,其实Apple算比较安全的了,反编译过来也就看到.h文件....但把代码混淆还是会比较好些. 一.iOS 中的网络加密 公司的 ...
- linux下 彻底修改python的包/模块导入路径
python模式下,有时候需要导入 import某些模块或者包.明明这个模块/包是存在的,却提示导入错误,比如,“ImportError: No module named lxml”. 但是当你在命 ...