IOS 自定义控件之-显示下载过程的ImageView
原创Blog,转载请注明出处
blog.csdn.net/hello_hwc
前言:这个系列的目的是为了提供一些思路,在Demo的过程中让读者学会一些自定义控件的思路,所以不适宜太复杂。当然,仅仅是抛砖引玉。这个控件我会上传Github,由于最近一直在搞IOT的应用,所以没时间把进行完善,有时间了我会把这个控件完善了,让读者那去直接就可以用。
完善好了我会更新下博客
Demo效果,支持两种显示过程的方式,沿着border绘制一圈和frame逐渐填充。
思路
- NSURLSessionDataTask下载图片
- 用Layer的方式展示下载的过程
接口设计
头文件源代码
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, WCProgressType) {
WCProgressTypeBorder,
WCProgressTypeFrame,
};
typedef void(^WCCompeltionBlock)(UIImage * image,NSError *error);
@interface WCProgressImageview : UIImageView
@property (nonatomic,getter=currentProgress,readonly)CGFloat progress;
@property (nonatomic,strong) NSString * url;
@property (nonatomic)WCProgressType type;
-(void)resume;
-(instancetype)initWithFrame:(CGRect)frame ImageURL:(NSString *)url Type:(WCProgressType)type;
-(instancetype)initWithFrame:(CGRect)frame ImageURL:(NSString *)url Type:(WCProgressType)type ComepetionHander:(WCCompeltionBlock)block;
@end
1.由于这个要支持两种类型,所以定义枚举代表分别为两种类型
2.定义block来给用户异步传递imageview加载完成的时间
3.只读属性progress获得当前下载的进度
4.url和type分别代表image的url和进度条的类型
5.提供两个API来初始化对象
实现
@interface WCProgressImageview()<NSURLSessionDelegate,NSURLSessionDataDelegate>
@property (strong,nonatomic)NSMutableData * buffer;
@property (nonatomic)NSUInteger expectlength;
@property (nonatomic,strong)CALayer * frameProgressLayer;
@property (nonatomic,strong)CAShapeLayer * borderProgressLayer;
@property (strong,nonatomic)NSURLSessionDataTask * dataTask;
@property (strong,nonatomic) NSURLSession * session;
@property (nonatomic,strong) WCCompeltionBlock completionBlock;
@property (nonatomic,getter=currentProgress,readwrite)CGFloat progress;
@end
@implementation WCProgressImageview
#pragma mark - property
-(NSMutableData *)buffer{
if (!_buffer) {
_buffer = [[NSMutableData alloc] init];
}
return _buffer;
}
-(CALayer *)frameProgressLayer{
if (!_frameProgressLayer) {
_frameProgressLayer = [CALayer layer];
_frameProgressLayer.backgroundColor = [UIColor lightGrayColor].CGColor;
_frameProgressLayer.bounds = CGRectMake(0,0,0,CGRectGetHeight(self.frame));
_frameProgressLayer.anchorPoint = CGPointMake(0,0);
_frameProgressLayer.position = CGPointMake(0,0);
}
return _frameProgressLayer;
}
-(CAShapeLayer *)borderProgressLayer{
if (!_borderProgressLayer) {
_borderProgressLayer = [CAShapeLayer layer];
_borderProgressLayer.bounds = CGRectMake(0,0,CGRectGetWidth(self.frame),CGRectGetHeight(self.frame));
_borderProgressLayer.anchorPoint = CGPointMake(0,0);
_borderProgressLayer.position = CGPointMake(0,0);
_borderProgressLayer.fillColor = [UIColor clearColor].CGColor;
_borderProgressLayer.lineWidth = 3.0;
_borderProgressLayer.path = [UIBezierPath bezierPathWithRoundedRect:_borderProgressLayer.bounds cornerRadius:10.0].CGPath;
_borderProgressLayer.strokeColor = [UIColor blueColor].CGColor;
_borderProgressLayer.strokeStart = 0.0;
_borderProgressLayer.strokeEnd = 0.0;
}
return _borderProgressLayer;
}
-(CGPathRef)createPathWith:(CGPoint *)center Radius:(CGFloat)radius Progress:(CGFloat)progress{
CGMutablePathRef mutablepath = CGPathCreateMutable();
return mutablepath;
}
-(NSURLSession *)session{
if (!_session) {
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
-(void)setUrl:(NSString *)url{
self.progress = 0;
self.dataTask = [self.session dataTaskWithURL:[NSURL URLWithString:url]];
}
#pragma mark - API
-(instancetype)initWithFrame:(CGRect)frame ImageURL:(NSString *)url Type:(WCProgressType)type{
if (self = [super initWithFrame:frame]) {
self.url = url;
self.type = type;
self.progress = 0;
}
return self;
}
-(instancetype)initWithFrame:(CGRect)frame ImageURL:(NSString *)url Type:(WCProgressType)type ComepetionHander:(WCCompeltionBlock)block{
if (self = [super initWithFrame:frame]) {
self.url = url;
self.completionBlock = block;
self.type = type;
self.progress = 0;
}
return self;
}
-(void)resume{
[self.dataTask resume];
switch (self.type) {
case WCProgressTypeFrame:
[self.layer addSublayer:self.frameProgressLayer];
break;
case WCProgressTypeBorder:
[self.layer addSublayer:self.borderProgressLayer];
break;
default:
break;
}
}
#pragma mark - URLSessionDelegate
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
NSHTTPURLResponse * httpresponse = (NSHTTPURLResponse *)response;
self.expectlength = [httpresponse expectedContentLength];
completionHandler(NSURLSessionResponseAllow);
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
[self.buffer appendData:data];
self.progress = self.buffer.length/(double)self.expectlength;
NSLog(@"%f",self.progress);
if (self.expectlength > 0) {
switch (self.type) {
case WCProgressTypeFrame:
self.frameProgressLayer.bounds = CGRectMake(0,0,CGRectGetWidth(self.frame) * self.progress,CGRectGetHeight(self.frame));
break;
case WCProgressTypeBorder:
self.borderProgressLayer.strokeEnd = self.progress;
break;
default:
break;
}
}
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
[self.frameProgressLayer removeFromSuperlayer];
self.frameProgressLayer = nil;
[self.borderProgressLayer removeFromSuperlayer];
self.borderProgressLayer = nil;
if (!error) {
UIImage * image = [UIImage imageWithData:self.buffer];
self.image = image;
if (self.completionBlock) {
self.completionBlock(image,error);
}
}else
{
self.completionBlock(nil,error);
}
[self clean];
}
-(void)clean{
self.buffer = nil;
[self.session invalidateAndCancel];
self.session = nil;
}
@end
讲解
1.属性采用惰性初始化
2.用CAShape Layer的StrokeEnd属性来代表进度
3.用NSURLSessionDelegate和NSURLSessionDataDelegate来获取数据和进度。
使用
self.imageview1 = [[WCProgressImageview alloc] initWithFrame:CGRectMake(40,40,300,200)
ImageURL:@"http://f12.topit.me/o129/10129120625790e866.jpg"
Type:WCProgressTypeBorder
ComepetionHander:^(UIImage *image, NSError *error) {
}];
[self.imageview1 resume];
[self.view addSubview:self.imageview1];
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。