基于Quartz 2D自定义加载进度视图
今天开始自己第一篇简书随笔文章,和iOS学习者共同分享自己在iOS开发中的一些学习经验。以前压根就没有写过什么博客文章之类的,但最近两天突然闪过一个念头:自已以往没事的身后也学习很多iOS相关的技术,有些东西虽然写过了,但一直放在那里,从来没有进行过系统的整理,事件久了很多东西也有些淡忘,所以就在想,干脆把自己以往写的一些东西拿出来和大家分享一下。自己也能温习一下以往所学的东西。
第一天,先从一个简单的小demo开始,自定义加载进度视图。可能没有好好研究过那些进度的加载视图,没有研究过Quartz 2D的iOS开发者,会认为类似那种微信图片加载的圆形进度显示图是一种什么很高大上的东西。其实不然,这种效果的实现非常简单,压根就不需要多少代码就能实现。其原理是基于Quartz 2D绘图引擎,先简单说下Quartz 2D这个绘图引擎,它支持跨平台。当然我所说的夸平台并不是说横夸各种平台,只是指iOS和OSX之间。
Quartz 2D的一些功能:
1.绘制图形
2.绘制文字
3.绘制\生成图像
4.读取\生成PDF
5.截图 裁剪图片
6.自定义UI控件
其实Quartz 2D的功能很强大,有很多东西都是基于它来实现的。如裁剪图片、涂鸦\画板、手势解锁、报表(折线图 饼状图 柱状图)等等,它还能做得事情远远不止于此。在app程序性能优化方面同样扮演着很重要的角色。当然,在绘制报表方面更建议大家使用一些第三方,如果想自己基于Quartz 2D绘制报表,实现起来还是很麻烦的一件事。关于Quartz 2D它的一些强大功能,今天就简单说这些,之前写过很多与它相关的小demo,如表格性能优化,手势解锁,绘制饼图,后期如果有时间,就会拿出来和大家共享。
步入今天的主题。首先来看下实现的效果图。
相关注释我会写在具体的代码中,另外以后没写一篇博客,会尽可能的附带上源码,具体的源码路径会放置在文章的末尾处。毕竟看源码才是最爽的事情。
1.ZWProgressView.h文件中
#import@interface ZWProgressView : UIView
@property(nonatomic,assign)CGFloat progress;
@end
2.ZWProgressView.m文件中
#import "ZWProgressView.h"
@interface ZWProgressView ()
@property(nonatomic,strong)UILabel *textLabel;
@end
@implementation ZWProgressView
- (instancetype)initWithFrame:(CGRect)frame{
if (self == [super initWithFrame:frame]) {
[self addSubview:self.textLabel];
}
return self;
}
- (void)setProgress:(CGFloat)progress{
_progress = progress;
self.textLabel.text = [NSString stringWithFormat:@"%.2f%%",progress * 100];
//手动调用这个方法,系统是不会生成和View相关联的上下文。
//只有系统调用drawRect方法时,才会生成和view相关联的上下文
[self drawRect:self.bounds];
//********************这个地方要额外注意*******************
//只有系统调用drawRect方法时,才会生成和view相关联的上下文
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
//画弧
CGPoint center = CGPointMake(rect.size.width/2, rect.size.height/2);
CGFloat radius = rect.size.width * 0.5 - 10;
CGFloat startA = -M_PI_2 ;
CGFloat endA = -M_PI_2 + self.progress * M_PI * 2;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
[[UIColor greenColor] set];
path.lineWidth = 5;
[path stroke];
}
- (UILabel *)textLabel{
if (_textLabel == nil) {
_textLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 150, 30)];
_textLabel.textAlignment = NSTextAlignmentCenter;
_textLabel.text = self.textLabel.text = @"0.00%";
_textLabel.center = self.center;
}
return _textLabel;
}
3.外部的调用。ViewController.m文件
#import "ViewController.h"
#import "ZWProgressView.h"
@interface ViewController ()
@property(nonatomic,strong)UISlider *slider;
@property(nonatomic,strong)ZWProgressView *zwProgressView;
@property (nonatomic,strong)UILabel *textLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.zwProgressView];
[self.view addSubview:self.slider];
}
- (ZWProgressView *)zwProgressView{
if (_zwProgressView == nil) {
_zwProgressView = [[ZWProgressView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
_zwProgressView.center = self.view.center;
[_zwProgressView addSubview:self.textLabel];
_zwProgressView.backgroundColor = [UIColor lightGrayColor];
}
return _zwProgressView;
}
- (UISlider *)slider{
if (_slider == nil) {
_slider = [[UISlider alloc]initWithFrame:CGRectMake(self.view.frame.size.width /2 - 100, CGRectGetMaxY(_zwProgressView.frame) + 20, 200, 50)];
[_slider addTarget:self action:@selector(valueChange:) forControlEvents:UIControlEventValueChanged];
}
return _slider;
}
- (void)valueChange:(UISlider *)sender {
NSLog(@"%f",sender.value);
//两个%代表一个%
self.zwProgressView.progress = sender.value;
}
@end
我就说了,这个并不是什么很高大上的东西,简单的一些代码就足够实现了。
最后附上源码下载地址(本人的github小号,以后专门用于和大家技术交流,不仅仅局限于iOS技术,H5、基于MUI框架的混合App开发等等):https://github.com/ZhengYaWei1992/ZWProgressView