2011-11-16 125 views
0

我建立我的表格視圖的自定義單元格。我試圖從互聯網加載圖片,爲此,我正在使用異步下載。圖像正在下載,但它沒有在我的手機中顯示此圖像。我已經嘗試在正常的視圖中顯示,並且工作正常。如果圖像已經下載,或者如果我滾動表格視圖並再次顯示單元格,它也可以工作。有人知道發生了什麼事嗎?IPhone - 下載異步工作,但加載異步不要

代碼:

DownloadImageManager.m

-(id)initWithImageName:(NSString *)imageAddress{ 
    self = [super initWithFrame:CGRectMake(10, 5, 100, 100)]; 
    if (self){ 
     self.urlString = imageAddress; 
     av = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; 
     av.frame = self.frame; 
     [av setBackgroundColor:[UIColor greenColor]]; 
     [self addSubview:av]; 
     [av startAnimating]; 
     [self checkImage]; 
    } 
    return self; 
} 

-(void)checkImage{ 
    bool isImageOnSysten = [self isImageOnFileSystem]; 
    if (isImageOnSysten) { 
     //If image is on the system, loads the image, it's working fine here 
     NSLog(@"CSantos: isImageOnSysten %@ is on system", self.urlString); 
    } else { 
     //here is the problem: 
     [self downloadImage]; 
    } 
} 

-(void)downloadImage{ 
    NSURL *url = [NSURL URLWithString:self.urlString]; 
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
    [request setDelegate:self]; 
    [request setAllowCompressedResponse:YES]; 
    [request setQueuePriority:NSOperationQueuePriorityLow]; 
    [request setDidFinishSelector:@selector(requestFinished:)]; 
    [request setDidFailSelector:@selector(requestFailed:)]; 
    [request setTimeOutSeconds:25]; 
    [request setNumberOfTimesToRetryOnTimeout:3]; 

    [request startAsynchronous]; 
} 

- (void)requestFinished:(ASIHTTPRequest *)request 
{ 
    NSData *responseData = [request responseData]; 
    NSArray *words = [self.urlString componentsSeparatedByString:@"/"]; 
    NSString *fileName = [words lastObject]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:fileName]; 
    NSError *error = nil; 
    [responseData writeToFile:writablePath options:NSDataWritingAtomic error:&error]; 
    NSLog(@"Write returned error: %@", [error localizedDescription]); 
    [av stopAnimating]; 
    [av removeFromSuperview]; 
} 

CellForProgram.m

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { 
    if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) { 

     textLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 31, 235, 40)] ; 
     [self.contentView addSubview:textLabel]; 

     photo = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 70, 70)]; 
     [photo setBackgroundColor:[UIColor blueColor]]; 
     photo.image = imagePhoto.image; 
     [self.contentView addSubview:photo]; 
    } 
    return self 

細胞來電

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"Cell"; 

    CellForProgram *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier] ; 
    if (cell == nil) { 
     cell = [[[CellForProgram alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    cell.textLabel.text = [speaker objectAtIndex:indexPath.row]; 

    DownloadImageManager *imageManager = [[DownloadImageManager alloc] initWithImageName:[images objectAtIndex:indexPath.row]]; 
    [cell.photo setImage:imageManager.image]; 
    return cell; 
} 

回答

0

我告訴我不需要在DownloadImageManager上做這種改變!但是,謝謝你的幫助,它幫助我完成了其他的事情!

CellForProgram.m

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { 
    if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) { 

     textLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 31, 235, 40)] ; 
     [self.contentView addSubview:textLabel]; 

     imagePhoto = [[DownloadImageManager alloc] initWithImageName:imageAdress.text]; 
     [self.contentView addSubview:imagePhoto]; 
    } 
    return self 
} 

DownLoadImageManager.m:添加此方法

-(void)changeImage:(NSString *)newImage{ 
    self.urlString = newImage; 
    [self checkImage]; 
} 

細胞來電

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"Cell"; 

    CellForProgram *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier] ; 
    if (cell == nil) { 
     cell = [[[CellForProgram alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    cell.textLabel.text = [speaker objectAtIndex:indexPath.row]; 

    [cell.imagePhoto changeImage:[images objectAtIndex:indexPath.row]]; 
    return cell; 
} 
1

你不與指針正常工作。

當您致電[cell.photo setImage:imageManager.image];並且圖像不存在時,您將它指向零或隨機存儲器空間。

您需要在DownloadImageManager類上創建一個指向您的單元格的指針,以便在圖像完成下載時更新單元格。

下面是我建議:

  • 創建指向您的自定義的UITableViewCell
  • 類不要設置上的tableView的圖像DownloadImageManager屬性:的cellForRowAtIndexPath:選擇。相反,請直接在DownloadImageManager上設置它。

這裏有一個簡單的修改代碼:

細胞來電

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"Cell"; 

    CellForProgram *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier] ; 
    if (cell == nil) { 
     cell = [[[CellForProgram alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    cell.textLabel.text = [speaker objectAtIndex:indexPath.row]; 

    DownloadImageManager *imageManager = [[DownloadImageManager alloc] initWithImageName:[images objectAtIndex:indexPath.row] andCell:cell]; 
    return cell; 
} 

DownloadImageManager.m

-(id)initWithImageName:(NSString *)imageAddress andCell:(CellForProgram*)cell{ 
    self = [super initWithFrame:CGRectMake(10, 5, 100, 100)]; 
    if (self){ 
     self.urlString = imageAddress; 
     self.cell = cell; 
     av = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; 
     av.frame = self.frame; 
     [av setBackgroundColor:[UIColor greenColor]]; 
     [self addSubview:av]; 
     [av startAnimating]; 
     [self checkImage]; 
    } 
    return self; 
} 

-(void)checkImage{ 
    bool isImageOnSysten = [self isImageOnFileSystem]; 
    if (isImageOnSysten) { 
     //If image is on the system, loads the image, it's working fine here 
     NSLog(@"CSantos: isImageOnSysten %@ is on system", self.urlString); 
     cell.photo = self.image; 
    } else { 
     //here is the problem: 
     [self downloadImage]; 
    } 
} 

-(void)downloadImage{ 
    NSURL *url = [NSURL URLWithString:self.urlString]; 
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
    [request setDelegate:self]; 
    [request setAllowCompressedResponse:YES]; 
    [request setQueuePriority:NSOperationQueuePriorityLow]; 
    [request setDidFinishSelector:@selector(requestFinished:)]; 
    [request setDidFailSelector:@selector(requestFailed:)]; 
    [request setTimeOutSeconds:25]; 
    [request setNumberOfTimesToRetryOnTimeout:3]; 

    [request startAsynchronous]; 
} 

- (void)requestFinished:(ASIHTTPRequest *)request 
{ 
    NSData *responseData = [request responseData]; 
    NSArray *words = [self.urlString componentsSeparatedByString:@"/"]; 
    NSString *fileName = [words lastObject]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:fileName]; 
    NSError *error = nil; 
    [responseData writeToFile:writablePath options:NSDataWritingAtomic error:&error]; 
    NSLog(@"Write returned error: %@", [error localizedDescription]); 
    [av stopAnimating]; 
    [av removeFromSuperview]; 

    cell.photo = self.image; 
} 

這應該讓你去。如果您需要澄清,請務必留言,我會盡快回復。

編輯:作爲替代方案,實現對DownloadImageManager的委託方法...

一下添加到DownloadImageManager。H:

@protocol DownloadImageManagerDelegate <NSObject> 
@optional 
- (void)DownloadFinished:(DownloadImageManager*)manager; 
@end 

取而代之的是CellForProgram的,使用DownloadImageManager協議,與此構造爲例:

,改變你的requestFinished的實現:像這樣:

- (void)requestFinished:(ASIHTTPRequest *)request 
{ 
    NSData *responseData = [request responseData]; 
    NSArray *words = [self.urlString componentsSeparatedByString:@"/"]; 
    NSString *fileName = [words lastObject]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:fileName]; 
    NSError *error = nil; 
    [responseData writeToFile:writablePath options:NSDataWritingAtomic error:&error]; 
    NSLog(@"Write returned error: %@", [error localizedDescription]); 
    [av stopAnimating]; 
    [av removeFromSuperview]; 

    if ([delegate respondsToSelector:@selector(DownloadFinished:)]) { 
     [delegate DownloadFinished:self]; 
    } 
} 

然後,使您的細胞達到給定的協議,如下所示:

- (void)DownloadFinished:(DownloadImageManager*)manager { 
    this.photo = manager.image; 
} 

這樣您就可以隨意地將您的功能保留在DownloadImageManager上。

+0

伴侶,這是不是一個真正的好主意。這正在改變DownloadImageManager,我可以在這個單元格中使用它。如果我嘗試在其他地方使用,我會收到很多錯誤消息。 – Claudio

+0

@Claudio我向協議/委託理念添加了答案,您可以使用它來保持您的下載類的功能,並且仍然可以解決您的問題。 –

+0

我剛剛說過:DownloadImageManager在所有其他接口中工作,但那一個(cell/tableview)。這不是課堂上的問題,而是我在這裏使用的方式。 – Claudio