2010-07-07 25 views
4

我有一個UITableView,我已在研究背景顏色通過力的UITableView傾倒所有可重複使用的細胞

UIView *myView = [[UIView alloc] init]; 
if ((indexPath.row % 2) == 0) 
    myView.backgroundColor = [UIColor greenColor]; 
else 
    myView.backgroundColor = [UIColor whiteColor]; 

cell.backgroundView = myView; 
[myView release]; 

我發現的是,當我編輯表中的問題設置(通過setEditing:是...)一些相同顏色的細胞不變,彼此相鄰。我如何強制UITableView完全重繪。 reloadData沒有做得很好。

是否有深度清洗重繪?

+0

做我的回答幫助? – 2010-07-07 20:22:37

回答

5

我有這個問題之前,所以我跟你我如何解決它分享:

您可以使用布爾標誌(說這就是所謂的needsRefresh)來控制細胞產生的-cellForRowAtIndexPath行爲:

一個例子:

- (UITableViewCell*) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath { 
    UITableViewCell *cell = [tableView dequeueResuableCellWithIdentifier:SOME_ID]; 
    if(!cell || needsRefresh) { 
     cell = [[[UITableViewCell alloc] init....] autorelease]; 
    } 
    //..... 
    return cell; 
} 

所以,當你需要一個硬性重新加載,設置needsRefresh標誌YES。簡單作爲一個疙瘩。

+0

它的工作原理。我的程序有一個非常複雜的單元格結構,所以我錯過了適用您的建議的正確位置。抱歉給你帶來不便。 – 2010-07-07 23:18:24

+0

這不會導致任何內存泄漏? – David 2011-05-27 15:57:24

+1

哦,是的,很好。 – 2011-05-27 19:03:26

3

對我來說,接受的答案並沒有真正的工作,因爲我不知道何時將needsRefresh設置爲YES。

什麼工作對我來說是:

- (UITableViewCell*) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath { 
    UITableViewCell *cell = [tableView dequeueResuableCellWithIdentifier:customCellIdentifier]; 
    if(nil == cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
             reuseIdentifier:customCellIdentifier]; 
    } 
    //..... 
    return cell; 
} 

然後你改變customCellIdentifier值,當您需要。這樣,如果切換回原始單元標識符,單元格也可以重新使用。

+0

我已經在下面放了一個稍微擴展的版本。 – 2014-08-11 08:48:51

0

我能夠通過向表數據源添加一個刷新變量來解決這個問題。我爲每個單元格使用了一個字典,但還有一個名爲@「refresh」的額外鍵:@「1」,表示單元需要刷新。一旦更新,我將該鍵的值設置爲@「0」。所以無論何時重新加載表,確保鍵再次回到@「0」。

0
#define TABLE_VIEW_CELL_DEFAULT_ID @"cellIdentifier" 
@property (nonatomic, strong) NSString *tableViewCellIdentifier; 
@property (nonatomic) NSUInteger tableViewCellIdentifierCount; 

// By using a different cell identifier, this effectively flushes the cell 
// cache because the old cells will no longer be used. 
- (void) flushTableViewCellCache 
{ 
    self.tableViewCellIdentifierCount++; 
    self.tableViewCellIdentifier = [NSString stringWithFormat:@"%@%i", TABLE_VIEW_CELL_DEFAULT_ID, self.tableViewCellIdentifierCount]; 
} 

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

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.tableViewCellIdentifier]; 
    if (cell == nil) { 
     cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:self.tableViewCellIdentifier]; 
    } 

    // rest of method... 
} 
1

接受的方法似乎很髒,它只是使一堆新的細胞與壞的一起存儲。這裏有幾個解決方案取決於你的情況:

1. 首先,對於問題中描述的情況,你不應該轉儲你的單元格並在每個週期創建新的視圖。您需要標記您的視圖,然後從電池拿回來的時候,當你得到一個複用小區:

- (UITableViewCell*) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath { 
    UITableViewCell *cell = [tableView dequeueResuableCellWithIdentifier:SOME_ID]; 
    if(!cell) { 
     cell = [[UITableViewCell alloc] init]; 

     UIView *myView = [[UIView alloc] init];  
     cell.backgroundView = myView; 

     [myView setTag:5]; //<------ 
    } 

    UIView *myView = [cell viewWithTag:5]; //<------ 
    if ((indexPath.row % 2) == 0) 
     myView.backgroundColor = [UIColor greenColor]; 
    else 
     myView.backgroundColor = [UIColor whiteColor]; 
    return cell; 
} 

//then just reload the tableview. 

2. ...甚至更好,爲什麼不使用電池backgrouncolor和更新,沒有創建一個視圖。

3. 確實清除舊的緩存單元格,它只是重新創建UITableView對象。

4. 在大多數情況下,您不需要銷燬這些單元格,只需跟蹤元素並在獲得可重用單元格後更新它們。您可以標記所有元素,保存數組引用,找到它們視圖層次結構......我確定了其他一些方法。

5。 繼承人一個襯墊直接清除所有細胞,雖然不是最好的做法惹這樣的物體的內部結構,因爲他們可能在未來的版本中改變:

[(NSMutableDictionary*)[tableview valueForKey:@"_reusableTableCells" ] removeAllObjects];