2010-07-07 7 views
4

J'ai un UITableView où je suis la couleur ANTÉCÉDENTS réglée viaforce UITableView pour vider toutes les cellules réutilisables

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

cell.backgroundView = myView; 
[myView release]; 

Le problème que je trouve est que lorsque je modifier une table (via setEditing: OUI ...) certains les cellules de la même couleur invariable sont les unes à côté des autres. Comment forcer UITableView à entièrement redessiner. reloadData ne fait pas du bon travail.

Y a-t-il un rafraîchissement en profondeur?

+0

a fait mon aide de réponse? –

Répondre

5

J'ai eu ce problème avant, donc je vais partager avec vous comment je l'ai résolu:

Vous pouvez utiliser un drapeau booléen (disons qu'il est appelé needsRefresh) pour contrôler le comportement de la création de cellules dans -cellForRowAtIndexPath:

un exemple:

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

Alors, quand vous avez besoin d'un rechargement dur, réglez le drapeau needsRefresh-YES. Simple comme un bouton.

+0

Cela fonctionne. Mon programme a une structure cellulaire très compliquée, donc j'avais raté le bon endroit pour appliquer votre suggestion. Désolé pour le dérangement. –

+0

cela ne provoquera-t-il pas de fuite de mémoire? – David

+1

Oh oui, bonne prise. –

3

Pour moi, la réponse acceptée n'a pas vraiment fonctionné puisque je n'avais aucune idée du moment où le paramètre needsRefresh revenait à YES.

Ce qui a fonctionné pour moi était:

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

Et puis vous modifiez la valeur de customCellIdentifier chaque fois que vous devez. De cette façon, les cellules sont également réutilisables si vous revenez à l'identifiant de cellule d'origine.

+0

J'ai mis une version légèrement étendue de ceci ci-dessous. –

0

J'ai été capable de résoudre ce problème en ajoutant une variable d'actualisation à la source de données de la table. J'ai utilisé un dictionnaire pour chaque cellule, mais il y a une touche supplémentaire appelée @ "refresh": @ "1", indiquant que la cellule a besoin d'être rafraichie. Une fois qu'il est mis à jour, je définis la valeur de cette clé sur @ "0". Donc, à chaque fois que la table est rechargée, assurez-vous que la touche remonte à @ "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

La méthode acceptée semble sale, elle fait juste un tas de nouvelles cellules qui sont stockées avec les mauvaises. Voici quelques solutions en fonction de votre situation:

1. D'abord, pour la situation décrite dans la question, vous ne devriez pas vider vos cellules et créer de nouvelles vues sur chaque cycle. Vous devez marquer votre point de vue, puis le récupérer quand de la cellule lorsque vous obtenez une cellule de réutilisation:

- (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. ... ou mieux encore, pourquoi ne pas simplement utiliser la backgrouncolor cellulaire et mise à jour sans créer une vue.

3. Un moyen sûr de vraiment effacer les vieilles cellules mises en cache pour simplement recréer l'objet UITableView. Dans la plupart des cas, vous n'avez pas besoin de détruire ces cellules, il suffit de garder une trace de vos éléments et de les mettre à jour après avoir récupéré la cellule réutilisable. Vous pouvez marquer tous vos éléments, les conserver la hiérarchie de vue ... Je suis sûr qu'il y a beaucoup d'autres façons.

5. Heres une doublure pour purger directement toutes les cellules, mais pas la meilleure pratique de jouer avec les objets internes de ce genre comme ils pourraient changer dans les futures versions:

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