iOS开发造轮子 | 封装一个自带loading的imageVi
2017-06-27 本文已影响836人
Lol刀妹
三笠
一.创建一个继承
为什么要封装这样一个东西?
来自实际项目:
用户点击按钮,弹出hud,hud里有一个imageView,imageView需加载后台设置的网络图片。如下:
现在的问题是:这张图片比较大,加载需要一点时间,在加载的这段时间内,图片显示的是默认的placeholder image。
如果用户网络不太好,可能这张图需要加载个3秒,这三秒内用户看到的都是placeholder image,这个时候用户可能会想:“这个是啥子哦!”,然后没等图片加载出来就点击hud取消了。
用户之所以会懵逼,是因为他不知道图片还在加载中,切确的说是我们没有友好的告诉他图片还在加载中。
那么怎样告诉用户图片还在加载中呢?
思路:在图片上放一个loading,图片加载完成前显示loading,加载完成后移除loading。
开始封装
用到的三方库:
1.Masonry (方便布局)
2.'ReactiveCocoa','~>2.1.8' (简化KVO的写法)
一.创建一个继承UIImageView
的子类,并规定它的构造方法:
#pragma mark - 构造方法
/**
构造方法
@param placeholderImage 默认占位图
@return 带默认占位图的loading imageView
*/
- (instancetype)initWithPlaceholderImage:(UIImage *)placeholderImage;
二.在初始化时就添加loading
#pragma mark - 添加loading
/** 添加loading */
- (void)addLoadingView{
// 背景
_loadingView = [[UIView alloc]init];
[self addSubview:_loadingView];
_loadingView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.5];
[_loadingView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(UIEdgeInsetsMake(0, 0, 0, 0));
}];
// 动画图片
UIImageView *animationImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"haha"]];
[_loadingView addSubview:animationImageView];
animationImageView.layer.cornerRadius = 20;
animationImageView.clipsToBounds = YES;
[animationImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(_loadingView.superview);
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
// 设置动画
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.autoreverses = NO;
animation.fromValue = [NSNumber numberWithFloat:0.f];
animation.toValue = [NSNumber numberWithFloat: M_PI *2];
animation.duration = 0.1; // 每秒10转,闪瞎你的眼
animation.repeatCount = MAXFLOAT; // 一直转
animation.fillMode = kCAFillModeForwards;
[animationImageView.layer addAnimation:animation forKey:nil];
}
三.获取图片加载完成的那个点
判断图片是否加载完成我用的一种间接方式:监听imageView的image,如果image变化就说明加载完成:
#pragma mark - 监听image的变化
/** 监听image的变化 */
- (void)observeImageChange{
[RACObserve(self, image) subscribeNext:^(id x) {
if (![x isEqual:_placeholderImage]) {
// 如果图片改变,移除loading图
[self removeLoadingView];
}
}];
}
四.加载完成后移除loading
#pragma mark - 移除loading
/** 移除loading */
- (void)removeLoadingView{
[_loadingView removeFromSuperview];
_loadingView = nil;
}
提供一个demo供参考
温馨提示
运行demo前请做好心理准备,当心被闪瞎。