在開發(fā)中银亲,我們難免會遇到這樣的需求帚屉,在tableView的cell上要顯示一張網(wǎng)絡(luò)圖片,cell的高度要根據(jù)網(wǎng)絡(luò)圖片的高度而定锌订。此時我們就要根據(jù)url來獲取網(wǎng)絡(luò)圖片的尺寸從而來布局cell眨业,廢話不多說急膀,首先第一種方法
//獲取image的size
+ (CGSize)getImageSizeWithURL:(NSURL*)url{
? ? if(![urlisKindOfClass:[NSURLclass]]||(url ==nil)) {
? ? ? ? returnCGSizeZero;
? ? }
? ? CGFloatwidth =0.0f, height =0.0f;
? ? UIImage *img = [[SDImageCache sharedImageCache]imageFromCacheForKey:url.absoluteString];
? ? if(img) {
? ? ? ? width = img.size.width;
? ? ? ? height = img.size.height;
? ? }else{
? ? ? ? CGImageSourceRefimageSourceRef =? ? CGImageSourceCreateWithURL((CFURLRef)url, NULL);
? ? ? ? if(imageSourceRef) {
? ? ? ? ? ? CFDictionaryRefimageProperties =CGImageSourceCopyPropertiesAtIndex(imageSourceRef,0,NULL);
? ? ? ? ? ? if(imageProperties !=NULL) {
? ? ? ? ? ? ? ? CFNumberRef widthNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
? ? ? ? ? ? ? ? //判斷設(shè)備是否為64位
#if defined(__LP64__) && __LP64__
? ? ? ? ? ? ? ? if(widthNumberRef !=NULL) {
? ? ? ? ? ? ? ? ? ? CFNumberGetValue(widthNumberRef, kCFNumberFloat64Type, &width);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? CFNumberRef heightNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
? ? ? ? ? ? ? ? if(heightNumberRef !=NULL) {
? ? ? ? ? ? ? ? ? ? CFNumberGetValue(heightNumberRef, kCFNumberFloat64Type, &height);
? ? ? ? ? ? ? ? }
#else
? ? ? ? ? ? ? ? if(widthNumberRef !=NULL) {
? ? ? ? ? ? ? ? ? ? CFNumberGetValue(widthNumberRef,kCFNumberFloat32Type, &width);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? CFNumberRef heightNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
? ? ? ? ? ? ? ? if(heightNumberRef !=NULL) {
? ? ? ? ? ? ? ? ? ? CFNumberGetValue(heightNumberRef,kCFNumberFloat32Type, &height);
? ? ? ? ? ? ? ? }
#endif
? ? ? ? ? ? ? ? CFRelease(imageProperties);
? ? ? ? ? ? }
? ? ? ? ? ? CFRelease(imageSourceRef);
? ? ? ? ? ? NSLog(@"Image dimensions: %.0f x %.0f px", width, height);
? ? ? ? }}
? ? returnCGSizeMake(width, height);
}
在根據(jù)url獲取到圖片的尺寸后,直接將size的高作為cell的高度坛猪。
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {
? ? ? ? ? ? CGSizeimageSize = [self getImageSizeWithURL:[NSURL URLWithString:[NSString getVedioUrl:dic[@"url"]]]];
? ? ? ? ? ? return imageSize.height* (kScreen_Width-20) / imageSize.width+4;
}
當然這種方法有弊端脖阵,它在獲取圖片尺寸的時候是很耗時的操作,所以會阻礙到主線程墅茉,從而造成界面卡頓,當所有圖片的尺寸都得到之后才會顯示UI呜呐。有興趣的同學(xué)可以嘗試一下新建線程異步獲取圖片尺寸就斤,獲取到尺寸之后重新刷新tableview,這也是后面第二種方法的思路蘑辑。
下面來說說第二種方法洋机,它是根據(jù)SDWebImage來處理的。我們都知道洋魂,每個圖片對應(yīng)的url都是唯一的绷旗,所以我們可以創(chuàng)建一個可變字典將圖片的url作為key值喜鼓,對應(yīng)的高度作為value值保存起來,加載完圖片后刷新tableview就好了衔肢。
//獲取網(wǎng)絡(luò)圖片的size庄岖,根據(jù)比例計算出圖片在APP中的高度
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {
? ? ? ? ? ? CGFloat photoHeight =0;
? ? ? ? ? ? for(NSString*url in[self.sizeDic allKeys]) {
? ? ? ? ? ? ? ? if([url isEqualToString:dic[@"url"]]) {
? ? ? ? ? ? ? ? ? ? photoHeight = [self.sizeDic[url] floatValue];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if(photoHeight >0) {
? ? ? ? ? ? ? ? returnphotoHeight;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? UIImageView*imageView = [[UIImageView alloc] init];
? ? ? ? ? ? ? ? [imageViewsd_setImageWithURL:[NSURL URLWithString:dic[@"url"]]] placeholderImage:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
? ? ? ? ? ? ? ? ? ? CGFloatheight = image.size.height* (kScreen_Width-20) / image.size.width+4;
? ? ? ? ? ? ? ? ? ? [self.sizeDic setObject:@(height) forKey:dic[@"url"]];
? ? ? ? ? ? ? ? ? ? [self.tableView reloadData];
? ? ? ? ? ? ? ? }];
? ? ? ? ? ? ? ? return0;
? ? ? ? ? ? }
}
其實第一種方法也可以新建線程異步處理,但是考慮到SDWebImage已經(jīng)幫我們處理好了角骤,此時就直接用第二種方法吧