到目前为止,我已经阅读了很多问题和答案[在这里或在网上],我无法找到问题的答案。
情况是:
我有一个包含UITableViewCell
的自定义UIImageView
,
我从服务器加载单元格的内容,这是按预期工作。
对于UIImageView
我开始下载图像的新线程,
但图像没有显示UNTIL我在DataBase中下载了整个项目!
我已尝试在互联网上放置一个示例图像的链接,这有点好[有一些延迟]
问题:
1. UIImgeView
未将其图像设置为“直到我加载整个表格”。
2. UIActivityIndicator
在加载图像之前停止运行。
我认为我做错了导致这些问题。
这是我的代码:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
OfferTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"OfferCell"];
cellHeight = cell.frame.size.height;
Offer * tmpOffer = _offersArray[indexPath.row];
[cell.likeButtonOutlet addTarget:self action:@selector(like:) forControlEvents:UIControlEventTouchUpInside];
[cell.disLikeButtonOutlet addTarget:self action:@selector(disLike:) forControlEvents:UIControlEventTouchUpInside];
//Offer Title
cell.offerTitle.text = tmpOffer.OfferTitle;
//Offer Image
[cell.offerImage setContentMode:UIViewContentModeScaleAspectFit];
cell.offerImage.image = [UIImage imageNamed:@"placeholder.png"];
if(!tmpOffer.imageLoaded){
dispatch_async(dispatch_get_global_queue(0,0), ^{
UIActivityIndicatorView * indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[cell.offerImage addSubview:indicator];
[indicator startAnimating];
tmpOffer.OfferImageObject = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:tmpOffer.OfferImage]]];
tmpOffer.imageLoaded = true;
[indicator stopAnimating];
[indicator removeFromSuperview];
[cell.offerImage setImage:tmpOffer.OfferImageObject];
cell.offerImage.clipsToBounds =YES;
cell.offerImage.layer.cornerRadius = 5;
tmpOffer.imageLoaded = true;
});
}
//Refresh the table if it shows the last cell
if(indexPath.row == _offersArray.count-1){
UILabel * updating = [[UILabel alloc]initWithFrame:CGRectMake(20, 20, 70, 30)];
updating.text = @"جاري التحديت ...";
#warning show updating message
[self refresh];
}
return cell;
}
,这是更新方法:
-(void)refresh{
NSMutableString * path = [NSMutableString stringWithString: @"api/Offers?$top=4&$skip="];
NSUInteger numOfElements = [_offersArray count];
NSString * strNumOfElements =[NSString stringWithFormat:@"%ld",(long)numOfElements];
[path appendString:strNumOfElements];
[[RKObjectManager sharedManager]getObjectsAtPath:path parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
int start = (int)_offersArray.count;
if(mappingResult.array.count !=0){
[_offersArray addObjectsFromArray: [mappingResult.array mutableCopy]];
NSMutableArray * indexesToBeReloaded = [[NSMutableArray alloc]init];
for(int i =start ; i<(int)_offersArray.count;i++){
[indexesToBeReloaded addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}
[self.tableView insertRowsAtIndexPaths:indexesToBeReloaded withRowAnimation:UITableViewRowAnimationNone];
}
else{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"لا عروض جديدة الان " message: @"وصلت إلى ابق بالقرب لمتابعة أفضل العروض (:" delegate:nil cancelButtonTitle:nil otherButtonTitles: @"حسناً",nil];
[alert show];
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:error.description delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles: @"",nil];
[alert show];
}
];
}
非常感谢您的帮助..
答案 0 :(得分:2)
所有与UI相关的工作都应该在主线程中完成。
您可能应该执行以下操作:
1)创建以URL为键,图像为值的图像字典。使用此功能可以在加载后保留图像副本,因此您只需执行一次。
2)不要在后台线程中进行任何UI更新。使活动指示器成为细胞的属性,以便细胞携带它。随着细胞的重复使用!你只需要创建一次。如果单元格图像位于字典中且活动不是nil,请确保将其删除并停止。如果需要加载图像,请根据需要创建活动并添加。在进行后台加载之前启动指示器。
3)在后台线程中,仅执行图像的加载。加载后,将调度同步到主线程,调用您添加的imageLoaded方法,该方法将图像作为参数,加载的单元格索引为索引。在此方法中,将图像添加到字典中并要求表重新加载indexPath处的行。这次单个单元格将停止指示器并显示图像,因为它将跟随2)。
这将确保您的单元格在图像到达时更新,并且所有UI操作都在主线程上发生。
您需要跟踪正在加载的图像,这样您才能进行多次运行。你在我当前的代码中已经考虑过这个问题,如果是这样的话,有人会在屏幕上滚动一个单元格并返回。
答案 1 :(得分:2)
在UITableViewCell中加载图像的最佳方法是AFNetworking UIImageView Category类。
将AFNetworking
库导入您的项目&amp; UIImageView+AFNetworking
课程也是如此。
#import "AFHTTPRequestOperation.h"
#import "UIImageView+AFNetworking.h"
然后在cellForRowAtIndexPath
内加载图片,如下所示。
__weak OfferTableViewCell *weakCell = cell;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:strImageLink]];
[weakCell.offerImage setImageWithURLRequest:request
placeholderImage:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.offerImage.image = image;
[weakCell setNeedsLayout];
} failure:nil];
这将为您异步完成所有事情