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];

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值