2011-09-20 183 views
2

我有一個自定義單元格,其中一些有圖像和其他人沒有的表格視圖。一切工作正常,但當我開始滾動時,單元格顯示不正確(圖像放置在「錯誤」單元格中並切割)。現在有人如何解決這個問題?UITableView滾動問題

+1

顯示單元構造的代碼會幫助你。 – Jhaliya

+0

代碼真的很大,但主要目的是在必要時添加圖像並相應地編輯單元格高度。 – superM

+0

你在桌子上使用多個部分? – Jhaliya

回答

4

要理解的關鍵是您的表單元格被重用。這樣做是爲了增加滾動的性能,因爲創建一個新的單元 - 這是一個視圖 - 是非常昂貴的。

在方法cellForRowAtIndexPath中,返回一個單元格。使用出隊方法的現有單元,或者您創建一個新單元。在那個單元格上,你可以設置你想表示的所有屬性。

我的猜測是你直接在單元格上設置這些屬性,如圖像等。然後,當您滾動時,該單元格被重用,並且您再次看到相同的圖像,但位於錯誤的單元格中。

所以,你需要的是像NSArray一樣的單獨索引來維護模型對象。該模型對象包含圖像的所有細節等。

讓我們舉一個例子。我有一個包含10個對象的數組,其中前五個是圖像「a.png」和第二個五個「b.png」。

如果我接收的cellForRowAtIndexPath的回調,我想要做如下:

的cellForRowAtIndexPath:(0,0)從陣列提供對象索引0,這是a.png 的cellForRowAtIndexPath:(0 ,1)從數組中提供一個索引爲1的對象,即a.png cellForRowAtIndexPath:(0,2)從數組索引2中提供對象,即a.png cellForRowAtIndexPath:(0,3)從數組a中提供對象索引3,即a.png cellForRowAtIndexPath:(0,4)從數組索引4提供對象,即a.png cellForRowAtIndexPath:(0,5)從數組索引5中提供對象,這是b.png cellForRowAtIndexPath:(0,6)從數組索引6提供對象,即b.png cellForRowAtIndexPath:(0,7)從數組中提供對象索引7,即b.png cellForRowAtIndexPath: (0,8)從陣列提供對象索引8,其b.png 的cellForRowAtIndexPath:(0,9)從陣列提供對象索引9,該b.png

現在,讓我們考慮在UITableView中,在封面下方,五個單元正在被重用。

對於每個調用以上,將出現以下情況:

的cellForRowAtIndexPath:(0,1)從陣列提供對象索引1,這是一個。png - 您嘗試將現有單元出列,但它返回「nil」,因此您創建了一個新單元。您設置模型對象的細節。

cellForRowAtIndexPath:(0,2)從數組中提供對象索引2,即a.png - 您試圖將現有單元出列,但它返回「nil」,因此您創建了新單元。您設置模型對象的細節。

cellForRowAtIndexPath:(0,3)從數組中提供對象索引3,即a.png - 試圖將現有單元出列,但它返回「nil」以便創建新單元。您設置模型對象的細節。

cellForRowAtIndexPath:(0,4)從數組中提供對象索引4,即a.png - 您嘗試出隊現有單元,但它返回「nil」,因此您創建了新單元。您設置模型對象的細節。

cellForRowAtIndexPath:(0,5)從數組中提供對象索引5,即b.png - 您試圖將現有單元出列並且它可以工作!您可以通過設置模型對象的細節再次使用該單元格

cellForRowAtIndexPath:(0,6)從數組中提供對象索引6,即b.png - 您試圖使現有單元出隊作品!您可以通過設置模型對象的細節再次使用該單元格

cellForRowAtIndexPath:(0,7)從數組中提供對象索引7,即b.png - 您試圖使現有單元出列作品!您可以通過設置模型對象的細節再次使用該單元格

cellForRowAtIndexPath:(0,8)從數組中提供對象索引8,即b.png - 您試圖使現有單元出隊作品!您可以通過設置模型對象的詳細信息再次使用該單元格

cellForRowAtIndexPath:(0,9)從數組中提供對象索引9,即b.png - 您試圖使現有單元出隊作品!您可以通過設置模型對象的詳細信息再次使用該單元格

對不起,如此冗長!我希望這有幫助。也許這是值得通過一個很好的表格視圖教程。肯定會有很多。

+0

非常感謝,它真的很有幫助。 – superM

+0

極好的例子。 – Jhaliya

+0

oops我做了一些數組索引錯誤。現在解決在上面的編輯。抱歉! –

0

您可能在創建單元格實例時添加圖像,而不是在表格視圖請求單元格視圖時添加圖像。例如:

這是正確的方法。每次表格視圖要求單元格時,我們都會設置圖像。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ident"]; 
    UIImageView *imageView; 
    if (cell == nil) { 
     cell = [UITableViewCell alloc] init ....]; 
     imageView = [[UIIMageView alloc] init]; 
     imageView.tag = 123; 
     [cell addSubview:imageView]; 
     [imageView release]; 
    } else { 
     imageView = [cell viewWithTag:123]; 
    } 

    imageView.image = ...; // load image here 
} 

這是錯誤的方法。我們在創建單元格時設置圖像。這會導致細胞在重新使用時出現錯誤的圖像。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ident"]; 
    if (cell == nil) { 
     cell = [UITableViewCell alloc] init ....]; 
     UIImageView *imageView = [[UIIMageView alloc] init]; 
     imageView.image = ...; 
     [cell addSubview:imageView]; 
     [imageView release]; 
    } 

} 
+0

所以,如果我說得對,下一個單元是在前一個單元的「基礎」上構建的? – superM

+0

類別。表視圖將只創建儘可能多的單元格視圖,因爲它需要放入一個屏幕。然後,當您向下滾動時,消失的頂部單元格將被重新使用並通過'dequeueReusableCellWithIdentifier'添加到底部。因此,每次調用cellForRowAtIndexPath時,都需要確保配置單元格,而不僅僅是在創建單元格視圖時。 –

+0

非常感謝您的幫助 – superM

2

嘗試更改單元格的標識符值。

NSString* identifierStr = [NSString stringWithFormat:@"ident_%d",indexPath.row]; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifierStr];