前言--這次我要探討的問題是一個(gè)不那么引人注意的地方,我認(rèn)為細(xì)節(jié)決定成敗,因此今天拿出來探討一下。針對(duì)于iOS的圖片加載---就拿最近比較火的電影《浮山行》做栗子了絮重。
上圖為使用SDWebImageManager加載網(wǎng)絡(luò)圖片的狀態(tài),可以輕易地看到圖片是有拉伸的。我們對(duì)UIImageView的填充模式進(jìn)行設(shè)置青伤,圖片也會(huì)多多少少看起來不那么順眼督怜。
通常會(huì)出現(xiàn)以下情況
- UIImageView沒有填充滿,兩邊有空白
- UIImageView有拉伸
原因:對(duì)UIImageView有固定的大小潮模,加載的圖片活動(dòng)范圍也就只有設(shè)置的那么大
如果我們把UIImageView的填充模式改變了亮蛔,圖片不會(huì)拉伸但是兩邊會(huì)有空白,顯然擎厢,這對(duì)排版來說究流,看起來會(huì)很雜亂。
我們希望看到的不是一個(gè)有拉伸的圖片动遭,并且加載的網(wǎng)絡(luò)圖片要將UIImageView填充完全芬探。
個(gè)人會(huì)采用等比剪切的方式進(jìn)行加載
像以上圖片這樣,雖然圖片看起來沒有顯示完全厘惦,但是它屬于圖片正中間偷仿,我們能夠看到圖片的主要內(nèi)容,并且看起來不會(huì)特別亂宵蕉。
首先會(huì)用到以下代碼酝静,用于對(duì)圖片的裁剪
+(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];
}
接下來,當(dāng)我們使用網(wǎng)絡(luò)加載圖片的時(shí)候就會(huì)用到SDWebImageManager羡玛。這是一個(gè)強(qiáng)大的三方别智,里面包含了大多數(shù)對(duì)圖片的處理。如果稼稿,您對(duì)SDWebImageManager只有簡(jiǎn)單的了解薄榛,僅僅用于加載圖片,但是對(duì)圖片填充有細(xì)節(jié)的要求让歼,我想這篇文章可能對(duì)你會(huì)有些許的幫助敞恋。
我將結(jié)合SDWebImageManager三方來談?wù)剤D片填充。上面谋右,講到要對(duì)圖片進(jìn)行裁剪硬猫,因此在我們需要加載圖片的時(shí)候我們會(huì)用到上面的裁剪方式。
我將裁剪方法寫在一個(gè)類里面改执,然后結(jié)合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) {
}];
});
});
} }
上面的代碼結(jié)合了許多,其中有關(guān)線程的暫且不談天梧,之后會(huì)單獨(dú)談?wù)勎覍?duì)線程的理解。
//判斷是否有緩存過
BOOL isExit = [[SDWebImageManager sharedManager] cachedImageExistsForURL:[NSURL URLWithString:imageName]];
這里的方法霞丧,調(diào)用的就是SDWebImageManager里面封裝的一個(gè)方法呢岗,他可以檢測(cè)是否圖片緩存過
//如果緩存里有,我們直接調(diào)用Cache里的圖片,以便節(jié)省下次網(wǎng)絡(luò)請(qǐng)求加載圖片
UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:imageName]; imageView.image = cachedImage;
這樣的方法也是SDWebImageManager里面的后豫。
如果緩存里面沒有悉尾,那么就在線程里面重新加載網(wǎng)絡(luò)圖片,下載完畢后就將圖片緩存起來挫酿。也就是else里面的語句构眯。
總結(jié)
1.加載圖片很簡(jiǎn)單,先裁剪
2.再檢查是否緩存
3.有緩存早龟,直接調(diào)用惫霸;沒有緩存,先下載葱弟,再緩存
最后壹店,SDWebImageManager里面有很多網(wǎng)絡(luò)加載的方法,里面囊括了許多iOS的知識(shí)芝加,可以抽時(shí)間仔細(xì)研究一下硅卢,說不定自己以后也能寫加載圖片的方法。以上是我通過學(xué)習(xí)SDWebImageManager藏杖,結(jié)合自己的理解和需求寫的加載圖片的方法将塑,雖有小問題,但是對(duì)于初學(xué)者來說蝌麸,或許會(huì)有些感悟点寥。我的方法結(jié)合了SDWebImageManager,所以或許會(huì)有些小問題祥楣,如果你不嫌棄可一起來探討开财,或者指出錯(cuò)誤。