前言--这次我要探讨的问题是一个不那么引人注意的地方,我认为细节决定成败,因此今天拿出来探讨一下。针对于iOS的图片加载---就拿最近比较火的电影《浮山行》做栗子了。
上图为使用SDWebImageManager加载网络图片的状态,可以轻易地看到图片是有拉伸的。我们对UIImageView的填充模式进行设置,图片也会多多少少看起来不那么顺眼。
通常会出现以下情况
- UIImageView没有填充满,两边有空白
- UIImageView有拉伸
原因:对UIImageView有固定的大小,加载的图片活动范围也就只有设置的那么大
如果我们把UIImageView的填充模式改变了,图片不会拉伸但是两边会有空白,显然,这对排版来说,看起来会很杂乱。
我们希望看到的不是一个有拉伸的图片,并且加载的网络图片要将UIImageView填充完全。
个人会采用等比剪切的方式进行加载
像以上图片这样,虽然图片看起来没有显示完全,但是它属于图片正中间,我们能够看到图片的主要内容,并且看起来不会特别乱。
首先会用到以下代码,用于对图片的裁剪
+(UIImage *)cutImage:(UIImage *)image imageView:(UIImageView *)imageView
{ //裁剪压缩图片
CGSize newSize;
CGImageRef imageRef = nil;
if ((image.size.width / image.size.height) < (imageView.frame.size.width / imageView.frame.size.height)) {
newSize.width = image.size.width;
newSize.height = image.size.width * imageView.frame.size.height / imageView.frame.size.width;
imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(0, fabs(image.size.height - newSize.height) / 2, newSize.width, newSize.height));
} else {
newSize.height = image.size.height;
newSize.width = image.size.height * imageView.frame.size.width / imageView.frame.size.height;
imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(fabs(image.size.width - newSize.width) / 2, 0, newSize.width, newSize.height));
}
return [UIImage imageWithCGImage:imageRef];
}
接下来,当我们使用网络加载图片的时候就会用到SDWebImageManager。这是一个强大的三方,里面包含了大多数对图片的处理。如果,您对SDWebImageManager只有简单的了解,仅仅用于加载图片,但是对图片填充有细节的要求,我想这篇文章可能对你会有些许的帮助。
我将结合SDWebImageManager三方来谈谈图片填充。上面,讲到要对图片进行裁剪,因此在我们需要加载图片的时候我们会用到上面的裁剪方式。
我将裁剪方法写在一个类里面,然后结合SDWebImageManager也将加载图片的方法写在类里面。
+(void)addImageWith:(NSString *)imageName andImageView:(UIImageView *)imageView{
BOOL isExit = [[SDWebImageManager sharedManager] cachedImageExistsForURL:[NSURL URLWithString:imageName]];
if (isExit) {
// NSLog(@"有");
UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:imageName];
imageView.image = cachedImage;
}else{
dispatch_queue_t ab = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_async(ab, ^{
[NSThread sleepForTimeInterval:2];
dispatch_async(main, ^{
NSURL *urlBack = [NSURL URLWithString:imageName];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:urlBack]];
image = [Cut cutImage:image imageView:imageView];
imageView.image = image;
//缓存图片
[[SDImageCache sharedImageCache] storeImage:image forKey:imageName];
[[SDWebImageManager sharedManager] downloadImageWithURL:urlBack options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
NSLog(@"下载完成");
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
}];
});
});
} }
上面的代码结合了许多,其中有关线程的暂且不谈,之后会单独谈谈我对线程的理解。
//判断是否有缓存过
BOOL isExit = [[SDWebImageManager sharedManager] cachedImageExistsForURL:[NSURL URLWithString:imageName]];
这里的方法,调用的就是SDWebImageManager里面封装的一个方法,他可以检测是否图片缓存过
//如果缓存里有,我们直接调用Cache里的图片,以便节省下次网络请求加载图片
UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:imageName]; imageView.image = cachedImage;
这样的方法也是SDWebImageManager里面的。
如果缓存里面没有,那么就在线程里面重新加载网络图片,下载完毕后就将图片缓存起来。也就是else里面的语句。
总结
1.加载图片很简单,先裁剪
2.再检查是否缓存
3.有缓存,直接调用;没有缓存,先下载,再缓存
最后,SDWebImageManager里面有很多网络加载的方法,里面囊括了许多iOS的知识,可以抽时间仔细研究一下,说不定自己以后也能写加载图片的方法。以上是我通过学习SDWebImageManager,结合自己的理解和需求写的加载图片的方法,虽有小问题,但是对于初学者来说,或许会有些感悟。我的方法结合了SDWebImageManager,所以或许会有些小问题,如果你不嫌弃可一起来探讨,或者指出错误。