IOS 自定义控件之-显示下载过程的ImageView
来源:互联网 发布:交朋友的软件 编辑:程序博客网 时间:2024/06/08 15:13
原创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];
1 0
- IOS 自定义控件之-显示下载过程的ImageView
- IOS 自定义控件之-显示下载过程的ImageView
- 【组合控件】android自定义控件之带文字的ImageView
- 自定义控件 imageview 双击显示红色边框
- Android自定义ImageView实现圆形控件显示
- 自定义类似ImageView的控件
- Android自定义控件之圆形进度条ImageView
- 自定义控件之 圆形 / 圆角 ImageView
- ImageView图像控件之裁剪和显示
- Android:FullImageView 自定义等比缩放的铺满控件显示的ImageView
- 显示下载的图片的imageview
- iOS开发之imageView居中显示图片
- android自定义带倒影的ImageView控件
- 自定义控件实现imageview的点击效果
- 自定义控件实现带进度条的ImageView
- Android自定义控件-不同形状的ImageView
- ImageLoader 下载图片显示到ImageView控件上
- 【Android 开发】:UI控件之显示图片控件 ImageView 的使用方法
- 数据存储大小端
- 黑马程序员——枚举中自有函数的调用
- 20150310总结
- (算法设计技巧与分析)Knapsack
- Castle学习系列
- IOS 自定义控件之-显示下载过程的ImageView
- android sqlite多线程读写分析与优化
- Git学习[二]
- 文章标题
- 笔试题目总结1
- (算法设计技巧与分析)Dijkstra
- C/C++面试总结必考题
- java深入分析I/O流工作机制01-写在分析之前
- 如何使VVdocumenter支持Xcode6