効果
#import <UIKit/UIKit.h>
@interface HWCircleView : UIView
@property (nonatomic, assign) CGFloat progress;
//进度条颜色
@property(nonatomic,strong) UIColor *progerssColor;
//进度条背景颜色
@property(nonatomic,strong) UIColor *progerssBackgroundColor;
//进度条的宽度
@property(nonatomic,assign) CGFloat progerWidth;
//进度数据字体大小
@property(nonatomic,assign)CGFloat percentageFontSize;
//进度数字颜色
@property(nonatomic,strong) UIColor *percentFontColor;
@end
#import "HWCircleView.h"
@interface HWCircleView ()
@property (nonatomic, weak) UILabel *cLabel;
@end
@implementation HWCircleView
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor clearColor];
//默认颜色
self.progerssBackgroundColor=[UIColor lightGrayColor];
self.progerssColor=[UIColor blueColor];
self.percentFontColor=[UIColor blueColor];
//默认进度条宽度
self.progerWidth=15;
//默认百分比字体大小
self.percentageFontSize=22;
//百分比标签
UILabel *cLabel = [[UILabel alloc] initWithFrame:self.bounds];
cLabel.font = [UIFont boldSystemFontOfSize:self.percentageFontSize];
cLabel.textColor = self.percentFontColor;
cLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:cLabel];
self.cLabel = cLabel;
}
return self;
}
- (void)setProgress:(CGFloat)progress
{
_progress = progress;
_cLabel.text = [NSString stringWithFormat:@"%d%%", (int)floor(progress * 100)];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
//路径
UIBezierPath *backgroundPath = [[UIBezierPath alloc] init];
//线宽
backgroundPath.lineWidth = self.progerWidth;
//颜色
[self.progerssBackgroundColor set];
//拐角
backgroundPath.lineCapStyle = kCGLineCapRound;
backgroundPath.lineJoinStyle = kCGLineJoinRound;
//半径
CGFloat radius = (MIN(rect.size.width, rect.size.height) - self.progerWidth) * 0.5;
//画弧(参数:中心、半径、起始角度(3点钟方向为0)、结束角度、是否顺时针)
[backgroundPath addArcWithCenter:(CGPoint){rect.size.width * 0.5, rect.size.height * 0.5} radius:radius startAngle:M_PI * 1.5 endAngle:M_PI * 1.5 + M_PI * 2 clockwise:YES];
//连线
[backgroundPath stroke];
//路径
UIBezierPath *progressPath = [[UIBezierPath alloc] init];
//线宽
progressPath.lineWidth = self.progerWidth;
//颜色
[self.progerssColor set];
//拐角
progressPath.lineCapStyle = kCGLineCapRound;
progressPath.lineJoinStyle = kCGLineJoinRound;
//画弧(参数:中心、半径、起始角度(3点钟方向为0)、结束角度、是否顺时针)
[progressPath addArcWithCenter:(CGPoint){rect.size.width * 0.5, rect.size.height * 0.5} radius:radius startAngle:M_PI * 1.5 endAngle:M_PI * 1.5 + M_PI * 2 * _progress clockwise:YES];
//连线
[progressPath stroke];
}
@end
使用
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, weak) HWCircleView *circleView;
- (void)viewDidLoad {
[super viewDidLoad];
//创建控件
HWCircleView *circleView = [[HWCircleView alloc] initWithFrame:CGRectMake(50, 200, 150, 150)];
[self.view addSubview:circleView];
self.circleView = circleView;;
//添加定时器
[self addTimer];
}
- (void)addTimer
{
//创建定时器
_timer = [NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
- (void)timerAction
{
_circleView.progress += 0.01;
if (_circleView.progress >= 1) {
[self removeTimer];
NSLog(@"完成");
}
}
- (void)removeTimer
{
[_timer invalidate];
_timer = nil;
}
<時間>
簡単に
setNeedsDisplayとsetNeedsLayoutの###### UIViewの方法
最初の2つの方法は、非同期で実行されています。setNeedsDisplayはあなたがUIGraphicsGetCurrentContextを得ることができるので、自動的に、機能を描画するためのdrawRectメソッドを呼び出して呼び出して、描画することができます。setNeedsLayoutのデフォルトのコールlayoutSubViews、あなたはデータサブビューのいくつかに対処することができます。アウトデータがlayoutSubViews便利ながら、魅力、setNeedsDisplay簡単な描画を要約します。
<時間>
layoutSubviewsは、次の場合に呼び出されます
1、INIT初期化がlayoutSubviewsをトリガしません。2、addSubviewトリガlayoutSubviews。図3に示すように、フレームトリガlayoutSubviewsのビューを設定し、もちろん、前提は、設定値のフレームの前と後に変更されます。4、UIScrollViewをローリングしてlayoutSubviewsをトリガします。5.電源を入れ画面layoutSubviewsイベントは、親のUIViewにトリガします。6、layoutSubviewsイベントは、親のUIView上でトリガするときのUIViewのサイズを変更します。7、直接setLayoutSubviewsを呼び出します。
<時間>
######のdrawRectは、次の場合に呼び出されます。
1、UIViewの初期化が、直接のdrawRectにつながる一切矩形サイズが自動的に呼び出されていないされていない場合。2回のコールの後のdrawRectメソッドController-> loadViewメソッド、あるController-、閲覧者のdrawRectを描くようになった>のviewDidLoad離れて、そのコントローラ心配しないで。これは(もしコントローラに見るためにいくつかの値を設定しますこれらは、いくつかの変数の値を使用する必要がある場合に表示)が描きます。
2は、メソッドがsizeToFit呼び出しの後に呼び出され、コールsizeToFitサイズを算出することが可能です。その後、システムは自動的にのdrawRect:メソッドを呼び出し。
3、UIViewContentModeRedraw contentModeプロパティの値を設定すること。:それは、自動的にフレームを設定または変更のdrawRectたびに呼び出されます。
4、直接呼び出しsetNeedsDisplay、またはsetNeedsDisplayInRect:トリガーのdrawRect:が、0 RECTすることができない前提があります。1,2-上記の推奨; 3,4-なく提唱
<時間>
######のdrawRectメソッドは注意ポイントを使用します。
図1に示すように、使用される場合のUIView描画、唯一のdrawRect:contextRefと適切な描画方法を得ます。買収の買収は、他の方法で参照を無効にして描画するために使用することができない場合。drawRect:メソッドを手動で呼び出しを示していない、あなたはsetNeedsDisplayまたはsetNeedsDisplayInRectを呼び出すことにより、システムが自動的に調整する方法を聞かせなければなりません。図2に示すように、使用される場合のCALayer図面のみdrawInContext:レンダリング(のdrawRectに類似)は、対応する方法、又は図面を委任。またsetNeedDisplayとリアルタイム描画に3つ以上を呼び出すために、他の間接的な方法を、呼び出している、あなたはtouchbeganだけsetNeedsDisplayでリアルタイムに画面をオフにリフレッシュするために他の方法を使用し、gestureRecognizerを使用することはできません
ます。https://my.oschina.net/u/2447911/blog/1837967で再現