加载图像到自定义表视图细胞异步

问题描述:

目前,我正在开发一个应用程序中,我有获取Facebook相册的照片作为 图库查看异步使用表格视图上使用下面的代码表视图单元格的按钮&放图片&显示:加载图像到自定义表视图细胞异步

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    NSLog(@"particulars..:%d",[particular count]); 
    int count=self.particular.count%3; 

    if(count==0) 
    { 
     return self.particular.count/3; 
    } 
    else 
    { 
     return (self.particular.count/3) +1; 
    } 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell1"; 
    CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
     { 
      [[NSBundle mainBundle] loadNibNamed:@"CustomTableViewCell" owner:self options:nil]; 
      cell = customcell; 
     } 


    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 

     dispatch_async(dispatch_get_global_queue(0,0), ^{ 
      NSString *buttonurl=[self.particular objectAtIndex:((indexPath.row)*3)+0]; 
      NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: buttonurl]]; 
      if (data == nil) 
       return; 
      dispatch_async(dispatch_get_main_queue(), ^{ 


       UIImage *image = [UIImage imageWithData:data]; 
       cell.accessoryType = UITableViewCellAccessoryNone; 
       cell.selectionStyle = UITableViewCellSelectionStyleNone; 
       cell.backgroundColor=[UIColor clearColor]; 
       [cell.first setBackgroundImage:image forState:UIControlStateNormal] ; 
       [cell.first addTarget:self action:@selector(original:) forControlEvents:UIControlEventTouchUpInside]; 
       [cell.first setContentMode:UIViewContentModeCenter] ; 
       cell.first.layer.cornerRadius = 10.0; 
       cell.first.layer.borderColor = [[UIColor grayColor]CGColor]; 
       cell.first.layer.borderWidth = 1.0f; 
       cell.first.backgroundColor=[UIColor clearColor]; 
       cell.first.tag = ((indexPath.row)*3)+1 ; 
       [spinner stopAnimating]; 
      }); 
      [data release]; 
     }); 

     if(((indexPath.row)*3)+3<[particular count]) 
     { 
      UIActivityIndicatorView *spinner2 = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
      UIActivityIndicatorView *spinner3 = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
      //spinner2.backgroundColor=[UIColor blackColor]; 
      CGRect frame= cell.second.frame; 
      spinner2.frame=frame; 
      //spinner2.frame=CGRectMake(112, y, 106, 106); 
      spinner2.hidesWhenStopped = YES; 
      [cell.second addSubview:spinner2]; 
      [spinner2 startAnimating]; 

      CGRect frame2= cell.third.frame; 
      spinner3.frame=frame2; 
      spinner3.hidesWhenStopped = YES; 
      [cell.third addSubview:spinner3]; 
      [spinner3 startAnimating]; 

      dispatch_async(dispatch_get_global_queue(0,0),^
      { 
       NSString *buttonurl=[self.particular objectAtIndex:((indexPath.row)*3)+1]; 
       NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: buttonurl]]; 

       NSString *buttonurl1=[self.particular objectAtIndex:((indexPath.row)*3)+2]; 
       NSData * data1 = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: buttonurl1]]; 
       if (data == nil) 
        return; 
       dispatch_async(dispatch_get_main_queue(),^
       { 
        UIImage *image = [UIImage imageWithData:data]; 
        UIImage *image1 = [UIImage imageWithData:data1]; 

        [cell.second setBackgroundImage:image forState:UIControlStateNormal] ; 
        [cell.second addTarget:self action:@selector(original:) forControlEvents:UIControlEventTouchUpInside]; 
        [cell.second setContentMode:UIViewContentModeCenter] ; 
        cell.second.layer.cornerRadius = 10.0; 
        cell.second.layer.borderColor = [[UIColor grayColor]CGColor]; 
        cell.second.layer.borderWidth = 1.0f; 
        cell.second.backgroundColor=[UIColor clearColor]; 
        cell.second.tag = ((indexPath.row)*3)+2 ; 
        NSLog(@"cell.second.tag:%d",cell.second.tag); 

        [cell.third setBackgroundImage:image1 forState:UIControlStateNormal] ; 
        [cell.third addTarget:self action:@selector(original:) forControlEvents:UIControlEventTouchUpInside]; 
        [cell.third setContentMode:UIViewContentModeCenter] ; 
        cell.third.layer.cornerRadius = 10.0; 
        cell.third.layer.borderColor = [[UIColor grayColor]CGColor]; 
        cell.third.layer.borderWidth = 1.0f; 

        cell.third.backgroundColor=[UIColor clearColor]; 
        cell.third.tag = ((indexPath.row)*3)+3 ; 
        NSLog(@"cell.third.tag:%d",cell.third.tag); 
        [spinner2 stopAnimating]; 
        [spinner3 stopAnimating]; 

       }); 
       [data release]; 
      }); 


     } 
     else if(((indexPath.row)*3)+2<[particular count]) 
     { 
      UIActivityIndicatorView *spinner2 = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
      CGRect frame1 = CGRectMake(120, y, 106, 107); 
      spinner2.frame=frame1; 
      spinner2.hidesWhenStopped = YES; 
      [cell.second addSubview:spinner2]; 
      [spinner2 startAnimating]; 
      dispatch_async(dispatch_get_global_queue(0,0),^
      { 
       NSString *buttonurl=[self.particular objectAtIndex:((indexPath.row)*3)+1]; 
       NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: buttonurl]]; 
       if (data == nil) 
        return; 
       dispatch_async(dispatch_get_main_queue(),^
       { 
        UIImage *image = [UIImage imageWithData:data]; 
        [cell.second setBackgroundImage:image forState:UIControlStateNormal] ; 
        [cell.second addTarget:self action:@selector(original:) forControlEvents:UIControlEventTouchUpInside]; 
        [cell.second setContentMode:UIViewContentModeCenter] ; 
        cell.second.layer.cornerRadius = 10.0; 
        cell.second.layer.borderColor = [[UIColor grayColor]CGColor]; 
        cell.second.layer.borderWidth = 1.0f; 
        cell.second.backgroundColor=[UIColor clearColor]; 
        cell.second.tag = ((indexPath.row)*3)+2 ; 
        NSLog(@"cell.second.tag:%d",cell.second.tag); 
        [spinner2 stopAnimating]; 

       }); 
       [data release]; 
      });   
     } 
     else 
     { 
      cell.second.hidden = YES; 
      cell.third.hidden = YES; 
     } 
     y=y+106; 
     return cell; 
    } 

此代码工作为我好,但问题是,当图像加载到按钮的表视图细胞含有那么如果我们向下滚动,然后它慢慢地显示图像,但在那之后,当我们向上滚动查看先前负载图像然后图像消失&它再次加载从开始&拿请告诉我在代码中犯的错误,或者我该如何解决这个问题?

+1

的图片加载缓慢,它开始重新加载,因为可重复使用的tableview细胞。它的好,如果你在数组中添加这些影像和数组加载到的tableview – Dany 2013-02-26 12:02:45

我建议你使用这个AsyncImageView。我已经使用它,它创造奇迹。要调用此API:

ASyncImage *img_EventImag = alloc with frame; 
NSURL *url = yourPhotoPath; 
[img_EventImage loadImageFromURL:photoPath]; 
[self.view addSubView:img_EventImage]; // In your case you'll add in your TableViewCell. 

与使用UIImageView相同。简单,它为你做大部分事情。 AsyncImageView在UIImageView中同时包含一个简单的类别,用于在iOS上异步加载和显示图像,以便它们不锁定UI,以及用于更高级功能的UIImageView子类。 AsyncImageView适用于URL,因此可以与本地或远程文件一起使用。

加载/下载的图像缓存在内存中,并在发生内存警告时自动清除。 AsyncImageView独立于UIImage缓存运行,但默认情况下,位于应用程序捆绑包根目录中的任何图像都将存储在UIImage缓存中,以避免重复缓存图像。

该库还可用于独立于UIImageView加载和缓存图像,因为它提供对底层加载和缓存类的直接访问。

有哪些做的工作的一些自定义库很好的为你

  1. AsynchImageView
  2. SDWebImage
  3. AFNetworking图像扩展(如果你使用AF)
+1

Lithu是正确的。你可以使用任何一个可以轻松完成工作的任务。 – 2013-02-26 13:19:36

据工作它应该做的方式。当您滚动表格视图时,就像消失的单元格已被释放,并且向后滚动单元格时出现。 所以,你应该用一个解决方案来缓存图像,使他们不需要再次加载,如EGOImageView(here),AsyncImageView,SDWebImage等做

这是一个使用dispatch_async的解决方案。如果你正在从服务的URL不是用这种方法NSObject的地方服务被称为

-(void)loadProfilePicWithURL:(NSString *)strUrl tagV:(NSInteger)tagV{ 
isProfilePicLoaded = NO; 
//set media tag as indexPath.row 

//call this method from cellForRowAtIndexpPath 
//Pass the image URL --> strProfilePicURL 
//Load the image in bg and set to imgProfilePic 
//After loaded, send a notification with tag to table view to update the cell 


NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:strUrl]]; 
imgProfilePic=[UIImage imageWithData:data]; 

isProfilePicLoaded = YES; 
[[NSNotificationCenter defaultCenter] postNotificationName:@"reloadTableViewCell" object:[NSNumber numberWithInteger:tagV]]; 
} 

呼叫从的cellForRowAtIndexPath

[self performSelectorInBackground:@selector(loadPic:) withObject:[NSNumber numberWithInteger:indexPath.row]]; 

这种方法实现

-(void)loadPic: (id)indexPath{ 
NSInteger conV=[indexPath integerValue]; 

NSObject *object=[Array objectAtIndex:conV]; 
[object loadProfilePicWithURL:object.url tagV:conV]; 

}

添加观察员通知NSObject

-(void)reloadTableViewCell:(NSNotification *)note{ 
NSInteger mediaTag = [[note object] integerValue]; 

[self reloadCellImage:mediaTag]; 

}

重新加载该表中的特定细胞。

-(void)reloadCellImage:(NSInteger)row{ 
NSObject *object = [self.receivedArray objectAtIndex:row]; 
NSIndexPath* rowToReload = [NSIndexPath indexPathForRow:row inSection:0]; 
customCell *cell = (customCell *)[self.tableView cellForRowAtIndexPath:rowToReload]; 
[cell.imgVw setImage:object.image];}