2016-10-01 49 views
0

我有一個問題,當我在表視圖中加載imageview。它的加載非常緩慢。我在表格視圖中使用了很多部分。有我的代碼:如何改善UITableview中的加載圖像?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
TrangChuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellTrangchu" forIndexPath:indexPath]; 

theGame *thegameObj; 
if([indexPath section] == 0){ 

    thegameObj = [theZingArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 1){ 

    thegameObj = [theBitArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 2){ 

    thegameObj = [theMobayArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 3){ 

    thegameObj = [theGateArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 4){ 

    thegameObj = [theVcoinArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 5){ 

    thegameObj = [theGarenaArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 6){ 

    thegameObj = [theOncashArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 7){ 

    thegameObj = [theMobiphoneArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 8){ 

    thegameObj = [theVinaphoneArray objectAtIndex:indexPath.row]; 

}else if([indexPath section] == 9){ 

    thegameObj = [theViettelArray objectAtIndex:indexPath.row]; 

} 
NSURL *urlImage = [NSURL URLWithString:thegameObj.image]; 
NSData *imageData = [NSData dataWithContentsOfURL:urlImage]; 
[email protected]"1"; 
UIImage *image= [UIImage imageWithData:imageData]; 
cell.imageView.layer.cornerRadius=5; 
cell.imageView.layer.masksToBounds=YES; 
cell.imageView.image = image; 
cell.labelName.text = thegameObj.objectName; 

if([[AppDelegate appDelegate]checkIP]) 
{ 
    [cell.txtQuantity setBackgroundColor:[UIColor whiteColor]]; 
    [cell.txtQuantity.layer setBorderColor:[UIColor grayColor].CGColor]; 
    [cell.txtQuantity.layer setBorderWidth:1.0]; 
    [cell.txtQuantity.layer setCornerRadius:5]; 
    cell.labelPrice.text = [NSString stringWithFormat:@"%@ (%@)", [NSNumberFormatter localizedStringFromNumber:thegameObj.price numberStyle:NSNumberFormatterDecimalStyle], loadCurrency]; 

} 
else 
{ 
    [cell.lbdetail setTitle:@"detail" forState:UIControlStateNormal]; 
    cell.txtQuantity.hidden=YES; 
    cell.labelPrice.hidden=YES; 
    cell.lbgia.hidden=YES; 
    cell.lbsl.hidden=YES; 
    cell.lbdetail.hidden=YES; 

} 

cell.objArray = thegameObj; 
cell.currency = loadCurrency; 
/* 
[cell.addToCartButton addTarget:self action:@selector(addToCart:) forControlEvents:UIControlEventTouchUpInside]; 
cell.addToCartButton.tag = [NSString stringWithFormat:@"%d_%d", (NSInteger)[indexPath section], (NSInteger)[indexPath row]]; 
*/ 
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 


return cell; 
} 

請幫我改進更快的加載圖像與UItableview中的很多部分。感謝您的解決方案!

回答

2

有一件事會幫助的是匹配分段表模型的數據結構,它是一個數組數組。你幾乎在那裏,因爲你有所有的子陣列。建立一個這樣的(當所有的子陣列建,而不是在cellForRow):

NSArray *model = @[ theZingArray, theBitArray, /*... and so on */]; 

,將讓您拼合大有條件的一行:

thegameObj = model[indexPath.section][indexPath.row]; 

您可以使用在其他地方像在numberRowsInSection

NSArray *sectionArray = model[indexPath.section]; 
return sectionArray.count; 

略微強硬的問題是有這些圖像加載異步和獲取緩存。完全原生的方法討論here和許多others

將這一想法告訴代碼,這裏的返回無論是緩存的圖片,或獲取,緩存和回報的方法...

// declare this and BE SURE TO INITIALIZE IT 
@property(strong,nonatomic) NSMutableDictionary *imageCache; 

// return an image found at the url string, if one is cached return it, otherwise, 
// fetch it, cache it and return it 
- (void)imageAtURLString:(NSString *)urlString completion:(void(^)(UIImage *, BOOL))completion { 
    if (self.imageCache[urlString]) { // if it's cached 
     completion(self.imageCache[urlString], YES); 
    } else { // fetch and cahce 
     NSURL *url = [NSURL URLWithString:urlString]; 

     NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 
      if (data) { 
       UIImage *image = [UIImage imageWithData:data]; 
       if (image) { 
        self.imageCache[urlString] = image; 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         completion(image, NO); 
        }); 
       } 
      } 
     }]; 
     [task resume]; 
    } 
} 

現在您簡化cellForRowAtIndexPath可以是這樣的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellid"]; // fixme 

    theGame *thegameObj = model[indexPath.section][indexPath.row]; 
    NSString *urlString = thegameObj.image; 
    UIImageView *imageView = cell.imageView; 

    [self imageAtURLString:urlString completion:^(UIImage *image, BOOL wasCached) { 
     if (wasCached) imageView.image = image; 
     else [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
    }]; 

    return cell; 
} 

這裏的想法是,你要麼有一個緩存的圖像,在這種情況下,只需設置單元格的imageView圖像,或者你必須提取一個。在提取的情況下,該行在提取期間是否滾動離開還不確定。重新加載當前行,使其更新(現在緩存)的圖像。

+0

感謝您的解答! –

2

有圖像緩存的概念,圖像視圖在後臺異步加載圖像。請參考以下鏈接 https://github.com/nicklockwood/AsyncImageView

+1

緩存和負載異步是不同的想法。有很多專門的UIImageView網絡代碼來完成它自己的加載,這是一個好主意(也很容易建立 - 無需網絡代碼)。這些圖像視圖實例自然會緩存圖像,但在滾動期間單元格被重用的表視圖中,這並沒有什麼好處。 – danh

0

在後臺使用下面的真棒庫下載圖像。

https://github.com/rs/SDWebImage

UIImageView * thumbnail = [[UIImageView alloc] init]; 
NSURL *urlToPicture1 = [NSURL URLWithString:currentMarker.thumbnail]; 

[thumbnail sd_setImageWithURL:urlToPicture1 placeholderImage:[UIImage imageNamed:@"placeholder.png"] options:SDWebImageProgressiveDownload completed:^(UIImage * image, NSError * error,SDImageCacheType cachedType, NSURL * imageURL){ 
    if(image){ 
     [thumbnail setImage:image]; 
     NSLog(@"Complete = %d, error = %@",cachedType, error); 
    } 
}]; 
+0

將圖像加載工作移動到圖像視圖是個不錯的主意,但它不足以包含在uitableview單元中的圖像視圖。視圖中的緩存過低,因爲視圖被重用。 – danh

+0

你可以檢查重用單元的解決方案:http://stackoverflow.com/questions/23741124/sdwebimage-uitableviewcell-wrong-image-when-scrolling – KKRocks