ios 自定义圆环加载进度

匿名 (未验证) 提交于 2019-12-02 23:43:01
效果

#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; }  

<hr>

简述一下

######UIView的setNeedsDisplay和setNeedsLayout方法

首先两个方法都是异步执行的。而setNeedsDisplay会调用自动调用drawRect方法进行绘制功能,这样可以拿到 UIGraphicsGetCurrentContext,就可以进行绘制了。而setNeedsLayout会默认调用layoutSubViews, 就可以 处理子视图中的一些数据。 综上所诉,setNeedsDisplay方便绘图,而layoutSubViews方便出来数据。

<hr>

layoutSubviews在以下情况下会被调用

1、init初始化不会触发layoutSubviews。 2、addSubview会触发layoutSubviews。 3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。 4、滚动一个UIScrollView会触发layoutSubviews。 5、旋转Screen会触发父UIView上的layoutSubviews事件。 6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。 7、直接调用setLayoutSubviews。

<hr>

######drawRect在以下情况下会被调用:

1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect调用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量值).

2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。

3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。

4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。 以上1,2推荐;而3,4不提倡

<hr>

######drawRect方法使用注意点:

1、若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate的ref并且不能用于画图。drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或者 setNeedsDisplayInRect,让系统自动调该方法。 2、若使用CAlayer绘图,只能在drawInContext: 中(类似于drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法 3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕

转载于:https://my.oschina.net/u/2447911/blog/1837967

文章来源: https://blog.csdn.net/weixin_34038652/article/details/92291023
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!