Question

Je suis capable de concevoir des UITableViewCells personnalisées et de les charger parfaitement à l'aide de la technique décrite dans le fil disponible à l'adresse http://forums.macrumors.com/showthread.php?t=545061 . Cependant, l'utilisation de cette méthode ne vous permet plus d'initier la cellule avec un identificateur reuseIdentifier, ce qui signifie que vous devez créer de toutes nouvelles instances de chaque cellule à chaque appel. Quelqu'un a-t-il trouvé un bon moyen de conserver en mémoire cache certains types de cellules à des fins de réutilisation, tout en pouvant néanmoins les concevoir dans Interface Builder?

Était-ce utile?

La solution

Il suffit d'implémenter une méthode avec la signature de méthode appropriée:

- (NSString *) reuseIdentifier {
  return @"myIdentifier";
}

Autres conseils

En fait, puisque vous construisez la cellule dans Interface Builder, définissez simplement l'identificateur de réutilisation:

 IB_reuse_identifier

Ou, si vous utilisez Xcode 4, consultez l'onglet Inspecteur d'attributs:

entrer la description de l'image ici

(Edit: une fois votre XIB généré par XCode, il contient un UIView vide, mais nous avons besoin d'un UITableViewCell; vous devez donc supprimer manuellement le UIView et insérer une cellule de vue tableau. Bien entendu, IB ne montrera aucun UITableViewCell paramètres pour un UIView.)

Maintenant, dans iOS 5, il existe une méthode UITableView appropriée pour cela:

- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier

Je ne me souviens pas de l'endroit où j'ai trouvé ce code à l'origine, mais cela fonctionne très bien pour moi jusqu'à présent.

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

    static NSString *CellIdentifier = @"CustomTableCell";
    static NSString *CellNib = @"CustomTableCellView";

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
        cell = (UITableViewCell *)[nib objectAtIndex:0];
    }

    // perform additional custom work...

    return cell;
}

Exemple de configuration d'Interface Builder ...

 alt text

Regardez la réponse que j'ai donnée à cette question:

Est-il possible de concevoir des sous-classes NSCell dans Interface Constructeur?

Il est non seulement possible de concevoir une UITableViewCell dans IB, mais il est également souhaitable, car sinon, tout le câblage manuel et le placement de plusieurs éléments sont très fastidieux. Performaance est acceptable si vous prenez soin de rendre tous les éléments opaques lorsque cela est possible. L'ID de réutilisation est défini dans IB pour les propriétés de UITableViewCell. Vous utilisez ensuite l'ID de réutilisation correspondant dans le code lorsque vous tentez de retirer de la file d'attente.

L’année dernière, certains présentateurs de la WWDC ont également fait savoir que vous ne devriez pas créer de cellules d’affichage de tableaux dans IB, mais que c’est une lourde charge.

À partir de la version 4.0 d’iOS, des instructions spécifiques dans la documentation iOS rendent ce processus extrêmement rapide:

http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7

Faites défiler jusqu'à l'endroit où il est question de la sous-classe UITableViewCell.

Voici une autre option:

NSString * cellId = @"reuseCell";  
//...
NSArray * nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:nil options:nil];

for (id obj in nibObjects)
{
    if ([obj isKindOfClass:[CustomTableCell class]])
    {
        cell = obj;
        [cell setValue:cellId forKey:@"reuseIdentifier"];
        break;
    }
}

Je crée mes cellules de vue personnalisées de la même manière, sauf que je la connecte via un IBOutlet.

L’approche [nib objectAt ...] est susceptible d’être modifiée en fonction de la position des éléments dans le tableau.

L'approche UIViewController est satisfaisante - venez de l'essayer et cela fonctionne assez bien.

MAIS ...

Dans tous les cas, le constructeur initWithStyle N'EST PAS appelé, aucune initialisation par défaut n'est donc effectuée.

J'ai lu divers articles sur l'utilisation de initWithCoder ou awakeFromNib , mais rien ne permet de conclure de manière concluante que l'un ou l'autre est la bonne façon.

À part l'appel explicite d'une méthode d'initialisation dans la méthode cellForRowAtIndexPath , je n'ai pas encore trouvé de réponse.

Il y a quelque temps, j'ai trouvé un excellent article de blog sur ce sujet à l'adresse blog.atebits.com et ont depuis commencé à utiliser la classe Loren Brichter ABTableViewCell pour exécuter tous mes UITableViewCells.

Vous vous retrouvez avec un simple conteneur UIView pour mettre tous vos widgets, et le défilement est extrêmement rapide.

J'espère que cela vous sera utile.

Cette technique fonctionne également et ne nécessite pas d’ivar funky dans votre contrôleur de vue pour la gestion de la mémoire. Ici, la cellule de vue de tableau personnalisée réside dans une xib nommée "CustomCell.xib".

 static NSData *sLoadedCustomCell = nil;

 cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
 if (cell == nil) 
 {
   if (sLoadedCustomCell == nil) 
   {        
      // Load the custom table cell xib
      // and extract a reference to the cell object returned
      // and cache it in a static to avoid reloading the nib again.

      for (id loadedObject in [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil]) 
      {
        if ([loadedObject isKindOfClass:[UITableViewCell class]]) 
        {
          sLoadedCustomCell = [[NSKeyedArchiver archivedDataWithRootObject: loadedObject] retain];
          break;
        }
    }
    cell = (UITableViewCell *)[NSKeyedUnarchiver unarchiveObjectWithData: sLoadedCustomCell];
  }

La méthode Louis a fonctionné pour moi. C’est le code que j’utilise pour créer le UITableViewCell à partir du nib:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];

    if (cell == nil) 
    {
        UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil];
        cell = (PostCell *)c.view;
        [c release];
    }

    return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *simpleTableIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}         

return cell;
}

La solution gustavogb ne fonctionne pas pour moi. Ce que j’ai essayé, c’est:

ChainesController *c = [[ChainesController alloc] initWithNibName:@"ChainesController" bundle:nil];
[[NSBundle mainBundle] loadNibNamed:@"ChaineArticleCell" owner:c options:nil];
cell = [c.blogTableViewCell retain];
[c release];

Cela semble fonctionner. BlogTableViewCell est l'IBOutlet de la cellule et ChainesController est le propriétaire du fichier.

D'après les documents UITableView concernant dequeueWithReuseIdentifier : "Chaîne identifiant l'objet de cellule à réutiliser. Par défaut, l'identifiant d'une cellule réutilisable est son nom de classe, mais vous pouvez le remplacer par n'importe quelle valeur arbitraire. "

Remplacer -reuseIdentifer vous-même est risqué. Que se passe-t-il si vous avez deux sous-classes de votre sous-classe de cellules et les utilisez dans une seule vue sous forme de tableau? S'ils envoient l'appel d'identifiant de réutilisation sur Super, vous retirerez une cellule de type incorrect .............. Je pense que vous devez remplacer la méthode reuseIdentifier, mais qu'elle renvoie un identifiant supplanté. chaîne. Ou, s’il n’en a pas été spécifié, renvoyer la classe sous forme de chaîne.

Pour ce qui en vaut la peine, j’ai interrogé un ingénieur de l’iPhone lors d’une des conférences techniques sur l’iPhone. Sa réponse a été "Oui, il est possible d'utiliser IB pour créer des cellules. Mais non. Merci de ne pas le faire. "

J'ai suivi les instructions d'Apple liées par Ben Mosher (merci!), mais j'ai constaté qu'Apple avait omis un point important. L'objet qu'ils conçoivent dans IB est simplement une UITableViewCell, de même que la variable qu'ils chargent à partir de celui-ci. Mais si vous le configurez en tant que sous-classe personnalisée de UITableViewCell et écrivez les fichiers de code pour la sous-classe, vous pouvez écrire des déclarations IBOutlet et des méthodes IBAction dans le code et les relier à vos éléments personnalisés dans IB. Il n’est alors pas nécessaire d’utiliser des balises de vue pour accéder à ces éléments et vous pouvez créer n’importe quel type de cellule folle que vous voulez. C'est le paradis du cacao.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top