2009-07-03 43 views
0

我正在編寫一個線程化的UITableView,它從網上檢索一些信息。我想在加載圖像時顯示活動指示符以代替常規cell.image。你如何在UITableViewCell中重新定位子視圖?

問題是自定義標籤和活動指示器表現不正常。標籤從適當的位置開始,活動指示器顯示在適當的位置並開始生成動畫,但只要在圖像下載線程上初次回調(基本上只加載一個圖像),視圖全部重置,就好像有一個參考,我被重置在一切的框架...

我重載 - (UITableViewCell的*)的tableView:(UITableView的*)的tableView的cellForRowAtIndexPath:(NSIndexPath *)indexPath;

有問題的代碼是在這裏:

// Set up the cell... 
    if(![[cell contentView] viewWithTag:indexPath.row+200]){ 
     UILabel *newLabel = [[UILabel alloc] init]; 
     newLabel.text = [[personList objectAtIndex:indexPath.row] name]; 
     newLabel.frame = [[cell contentView] frame]; 
     [[cell contentView] addSubview:newLabel]; 
     newLabel.tag = indexPath.row+200; 
     [newLabel release]; 
    } 
    else{ 
     UILabel *alreadySetLabel = (UILabel *)[[cell contentView] viewWithTag:indexPath.row+200]; 
     alreadySetLabel.text = [[personList objectAtIndex:indexPath.row] name]; 
     alreadySetLabel.frame = [[cell contentView] frame]; 
    } 

    UIImageView *tmpImageView = cell.imageView; 

    NSLog(@"In cell name: %@", [[personList objectAtIndex:indexPath.row] name]); 
    NSLog(@"In cell profile image: %@", [[personList objectAtIndex:indexPath.row] profileImage]); 

    if([[personList objectAtIndex:indexPath.row] profileImage]){ 
     tmpImageView.image = [[personList objectAtIndex:indexPath.row] profileImage]; 
     [[[cell contentView] viewWithTag:indexPath.row+100] removeFromSuperview]; 
     UILabel *labelRef1 = (UILabel *)[[cell contentView] viewWithTag:indexPath.row+200]; 
     [labelRef1 setFrame:CGRectMake(cell.contentView.frame.origin.x+70, cell.contentView.frame.origin.y, labelRef1.frame.size.width, labelRef1.frame.size.height)]; 
    } 
    else{ 
     NSLog(@"%@", [[personList objectAtIndex:indexPath.row] imageFilePath]); 
     if(![[cell contentView] viewWithTag:indexPath.row+100] && [[personList objectAtIndex:indexPath.row] imageFilePath]){ 
      UIActivityIndicatorView *newSpin = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
      [newSpin setTag:indexPath.row+100]; 
      [newSpin startAnimating]; 
      [newSpin setFrame:CGRectMake(5, ((cell.contentView.frame.size.height/2)-7), 30, ((cell.contentView.frame.size.height/2)-7)+15) ]; 
      [[cell contentView] addSubview:newSpin]; 
      [newSpin release]; 
      UILabel *labelRef2 = (UILabel *)[cell viewWithTag:indexPath.row+200]; 
      [labelRef2 setFrame:CGRectMake(cell.contentView.frame.origin.x+70, cell.contentView.frame.origin.y, labelRef2.frame.size.width, labelRef2.frame.size.height)]; 
     } 
    } 

品牌新的iPhone應用程序開發,不到兩個星期我想知道如果我誤解了使用標籤?在我看來,如果你可以將標籤值鏈接到indexPath,你可以拿出唯一的標識符來引用自定義視圖? 100和200是任意值,這樣我就不會意外地在單個屏幕數據中重複使用標籤 - 不知道這是否必要,因爲我認爲標籤只能通過子視圖搜索。

在此先感謝您的任何建議。也歡迎就如何使這更優雅的一般技巧...

感謝, 喬希

回答

1

我不知道究竟你的「意見全部復位的意思,好像有一個參考和我正在重新設置所有這些框架「,但讓我指出一些事情。一般使用標籤和加載表格視圖單元格圖像。

標籤都只是一種內一個視圖識別/檢索子視圖 - 他們沒有被全球獨特。實際上,在標記值中併入indexPath.row根本不是一個好主意,因爲表視圖單元格獲得重用(只要您使用dequeueReusableCellWithIdentifier:,您絕對應該這樣做)。此外,我會將標記值定義爲常量(例如#define),並只在您的代碼中引用這些常量。這樣你的代碼就更具描述性,不易出錯並且更易於維護。

說實話,我不喜歡使用標籤。事實上,在tableView:cellForRowAtIndexPath:「在飛行中」構建表格視圖單元格是我遇到的唯一沒有替代方案的情況(因爲您沒有任何指定的插座)。我建議你將子類UITableViewCell而不是搞亂標籤。這實際上沒什麼大不了的,但是你的代碼會更乾淨,你可以很容易地將所有與單元相關的東西封裝在這個類中 - 當你做更復雜的事情時尤其重要,比如在網絡上異步加載表格視圖單元格圖像。

關於異步圖像加載東西,你看看this project on github?它基本上是演示項目,演示如何異步加載(flickr)圖像並在完成加載時將其更新爲表視圖 - 這不是一個完美的實現,但至少是一個好的起點。我最近做了同樣的事情,但我的方法是子類UIImageView,並執行此子類中的所有異步加載/更新。主要原因是我想要一個通用的可重用解決方案。

0

你是對的 - 子類化單元本來就是封裝和代碼量的途徑。我必須改變這一點。

在附註上,我用一個額外的代碼分支解決了這個問題。

爲了澄清,問題是我添加到子視圖的自定義標籤每次重新裝入數據表時都會重置其框架。您會注意到我將它移動超過70個像素,以爲活動指示器或已加載的圖像留出空間。它會在第一次通過時執行此操作,然後在每次從後臺線程加載回來的附加圖片時重置爲origin.x = 0。

顯然,標籤框架將被重置,不管是什麼?我的代碼會在單元格contentView中檢測到標籤爲100的子視圖(我按照您的建議將其更改爲靜態值,就像我以前那樣),並且什麼都不做,因爲我的印象是,矩形會保持靜止不變作爲觀點存在。事實並非如此,無論是否已經存在,我都必須明確地設置幀。無論如何,可能只是我完全不理解發生了什麼。只要我在別的地方添加了一個setFrame,一切正常。

謝謝, Josh

相關問題