在滚动tableview目标时图像放置不当c

时间:2017-05-14 14:09:44

标签: ios objective-c uitableview

你好我们从我的服务器下载每个产品的图像并将其设置在我的 UITableView 的自定义单元格中,并在向下滚动 UITableView 后将它们缓存在磁盘上图像被错过了我的意思是新单元格在搜索到这个主题后获取前一个单元格的旧值我发现了不同的解决方案要么使用 prepareForReuse ,要么检查单元格是否为nil或者两者都没有他们不适合我的情况。

CODE: MyCustomCell.h

#import <UIKit/UIKit.h>
#import "mirsaProduct.h"
#import "SVProgressHUD.h"
#import "AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#import "SDWebImageCompat.h"
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageDownloader.h"
#import "SDImageCache.h"
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageManager.h"
#import "SDWebImageDecoder.h"
#import "SDWebImagePrefetcher.h"

    @interface mirsaProductTableViewCell : UITableViewCell
    @property (weak, nonatomic) IBOutlet UILabel *mirsaProductTitle;
    @property (weak, nonatomic) IBOutlet UITextView *mirsaProductDescription;
    @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *mirsaProductActivityIndicatorView;
    @property (weak, nonatomic) IBOutlet UIImageView *mirsaProductLogoImageView;    
    @end


**MyCustomCell.m**

#import "mirsaProductTableViewCell.h"

@implementation mirsaProductTableViewCell

@synthesize mirsaProductTitle = _mirsaProductTitle;
@synthesize mirsaProductDescription = _mirsaProductDescription;
@synthesize mirsaProductLogoImageView = _mirsaProductLogoImageView;
@synthesize mirsaProductActivityIndicatorView = _mirsaProductActivityIndicatorView;

-(void)prepareForReuse
{

}
- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}





@end

myTableViewController.h

#import <UIKit/UIKit.h>
#import "mirsaCategories.h"
#import "sharedManagers.h"
#import "mirsaProductTableViewCell.h"
#import "constant.h"
#import "SVProgressHUD.h"
#import "AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#import "SDWebImageCompat.h"
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageDownloader.h"
#import "SDImageCache.h"
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageManager.h"
#import "SDWebImageDecoder.h"
#import "SDWebImagePrefetcher.h"
#import "mirsaProduct.h"
#import "mirsaDetailedProductViewController.h"
#import "mirsaProductDetailsTableViewController.h"
@interface mirsaProductsTableViewController : UITableViewController
@property (nonatomic,strong) mirsaCategories *currentCategory;
@property (nonatomic,strong) NSMutableArray *listOfProducts;
@property (nonatomic,strong) mirsaProduct *currentProduct;

@end

myTableViewController.m 由于没有让问题太长,我只是将cellOfRowAtIndexPath及相关方法导入其中。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"mirsaProductCell";
    mirsaProductTableViewCell *cell = (mirsaProductTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];



    if (cell == nil) {

        cell = [[mirsaProductTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] ;
        cell.mirsaProductLogoImageView.layer.cornerRadius = 50.0f;
        cell.mirsaProductLogoImageView.layer.borderWidth = 1.5f;
        cell.mirsaProductLogoImageView.clipsToBounds = YES;
        cell.mirsaProductLogoImageView.layer.borderColor = [UIColor colorWithRed:redRedColor green:redGreenColor blue:redBlueColor alpha:ALFA].CGColor;
        mirsaProduct *currentProduct = [self.listOfProducts objectAtIndex:indexPath.row];

        cell.mirsaProductTitle.text = [NSString stringWithFormat:@"Product Code:%@",currentProduct.mirsaProductCode];
        cell.mirsaProductDescription.text = [NSString stringWithFormat:@"Description: %@",currentProduct.mirsaProductDescription];
        [self downloadProductLogoImageView:cell :indexPath.row];
         for (int i = 0; i < currentProduct.mirsaProductUrlImage.count; i++) {
            [self downloadImageWithCached:currentProduct.mirsaProductUrlImage[i] :cell :indexPath.row :(NSInteger)i];
        }
    }


    else

    {
        cell.mirsaProductLogoImageView.layer.cornerRadius = 50.0f;
        cell.mirsaProductLogoImageView.layer.borderWidth = 1.5f;
        cell.mirsaProductLogoImageView.clipsToBounds = YES;
        cell.mirsaProductLogoImageView.layer.borderColor = [UIColor colorWithRed:redRedColor green:redGreenColor blue:redBlueColor alpha:ALFA].CGColor;
        mirsaProduct *currentProduct = [self.listOfProducts objectAtIndex:indexPath.row];

        cell.mirsaProductTitle.text = [NSString stringWithFormat:@"Product Code:%@",currentProduct.mirsaProductCode];
        cell.mirsaProductDescription.text = [NSString stringWithFormat:@"Description: %@",currentProduct.mirsaProductDescription];
        [self downloadProductLogoImageView:cell :indexPath.row];
        for (int i = 0; i < currentProduct.mirsaProductUrlImage.count; i++) {
            [self downloadImageWithCached:currentProduct.mirsaProductUrlImage[i] :cell :indexPath.row :(NSInteger)i];
        }
    }


    return cell;
}






-(void)downloadProductLogoImageView:(mirsaProductTableViewCell *)cell :(NSInteger )index;
{
    @autoreleasepool {
        [cell.mirsaProductActivityIndicatorView startAnimating];
        mirsaProduct *currentProduct  = [self.listOfProducts objectAtIndex:index];
        NSString *cachedKey  = currentProduct.mirsaProductImage;
        SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:@"productLogoImageView"];
        [imageCache queryDiskCacheForKey:cachedKey done:^(UIImage *image, SDImageCacheType cacheType)

         {
             if (image) {


                 dispatch_async(dispatch_get_main_queue(), ^{
                     [cell.mirsaProductActivityIndicatorView stopAnimating];
                     cell.mirsaProductLogoImageView.image = image;

                 });
             }else{

                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                     NSURL *url  = [NSURL URLWithString:currentProduct.mirsaProductImage];
                     [[SDWebImageDownloader sharedDownloader]downloadImageWithURL:url options:SDWebImageDownloaderLowPriority progress:^(NSInteger receivedSize, NSInteger expectedSize) {
                     } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {




                         if (finished && image){
                             dispatch_async(dispatch_get_main_queue(), ^{

                                 [imageCache setMaxCacheAge:60*60*24];

                                 [imageCache storeImage:image
                                   recalculateFromImage:NO
                                              imageData:data
                                                 forKey:currentProduct.mirsaProductImage
                                                 toDisk:YES];
                             });



                             [cell.mirsaProductActivityIndicatorView stopAnimating];
                             cell.mirsaProductLogoImageView.image = image;


                         }


                     }];









                 });
             }
         }];






    }


}

我在堆栈溢出Tableview images chaging when scrolling using custom tableviewIncorrect cell data display when scrolling UITableView

上找到的一些链接

2 个答案:

答案 0 :(得分:1)

您好我完成了您的代码,有两个重大变化需要解决您的问题

  1. if(cell == nil){

    cell = [[mirsaProductTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] ;
    cell.mirsaProductLogoImageView.layer.cornerRadius = 50.0f;
    
  2. 这行代码中的

    不使用nil而不是使用单元格标识符

    1. 下载图片,你不需要编写那么多代码就可以写

      [imageView sd_setImageWithURL:[NSURL URLWithString:@“http://www.example.com/path/to/image.jpg”]              placeholderImage:[UIImage imageNamed:@“placeholder.png”]];

答案 1 :(得分:0)

像SDWebImage这样的第三方库是一个合理的想法,虽然简单的自制版本并不难创建。而不是单元格中的常规图像视图,使用您自己的子类,如下所示:

// .h
#import <UIKit/UIKit.h>
@interface AsynchImageView : UIImageView
- (void)setImageFromUrl:(NSString *)url placeholder:(UIImage *)placeholder;
@end

// .m
#import "AsynchImageView.h"

@implementation AsynchImageView

- (void)setImageFromUrl:(NSString *)url placeholder:(UIImage *)placeholder {
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    NSURLCache *cache = [NSURLCache sharedURLCache];
    NSCachedURLResponse *cachedResponse = [cache cachedResponseForRequest:request];
    if (cachedResponse) {
        [self setImageFromData:cachedResponse.data];
    } else {
        self.image = placeholder;
        NSURLSession *session = [NSURLSession sharedSession];
        [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            if (!error) {
                [cache storeCachedResponse:[[NSCachedURLResponse alloc] initWithResponse:response data:data] forRequest:request];
                [self setImageFromData:data];
            }
        }] resume];
    }
}

- (void)setImageFromData:(NSData *)data {
    UIImage *image = [UIImage imageWithData:data];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.image = image;
    });
}

@end

检查图像是否已经下载,如果没有,则设置占位符图像并开始下载。完成后,它会将图像设置为下载的图像并进行缓存。

配置单元格时删除所有其他图像代码,并执行以下操作:

NSString *url  = currentProduct.mirsaProductImage;
[cell.mirsaProductLogoImageView setImageFromUrl: placeholder:];