web-dev-qa-db-fra.com

Définition du style de UITableViewCell lors de l'utilisation de iOS 6 UITableView dequeueReusableCellWithIdentifier: forIndexPath:

J'essaie de déterminer comment définir la UITableViewCellStyle lorsque j'utilise les nouvelles méthodes dans iOS 6 pour UITableView.

Auparavant, lors de la création d'une UITableViewCell, je changeais l'énumération UITableViewCellStyle pour créer différents types de cellules par défaut lors de l'appel de initWithStyle:, mais d'après ce que je peux rassembler, ce n'est plus le cas.

La documentation Apple pour UITableView indique:

Valeur de retour : Un objet UITableViewCell avec l'identificateur de réutilisation associé. Cette méthode retourne toujours une cellule valide.

Discussion : Pour des raisons de performances, la source de données d'une vue table doit généralement réutiliser les objets UITableViewCell lorsqu'elle attribue des cellules à des lignes dans sa méthode tableView: cellForRowAtIndexPath:. Une vue de table conserve une file d'attente ou une liste d'objets UITableViewCell que la source de données a marqués pour être réutilisés. Appelez cette méthode à partir de votre objet de source de données lorsqu'il vous est demandé de fournir une nouvelle cellule pour la vue tabulaire. Cette méthode supprime la file d'attente d'une cellule existante, le cas échéant, ou en crée une nouvelle en fonction du fichier de classe ou nib que vous avez précédemment enregistré.

Important : Vous devez enregistrer un fichier de classe ou un fichier nib à l'aide de la méthode registerNib: forCellReuseIdentifier: ou registerClass: forCellReuseIdentifier: avant de l'appeler.

Si vous avez enregistré une classe pour l'identificateur spécifié et qu'une nouvelle cellule doit être créée, cette méthode initialise la cellule en appelant sa méthode initWithStyle: reuseIdentifier:. Pour les cellules basées sur nib, cette méthode charge l'objet cellule à partir du fichier nib fourni. Si une cellule existante était disponible pour une réutilisation, cette méthode appelle à la place la méthode prepareForReuse de la cellule.

Voici comment ma nouvelle cellForRowAtIndexPath se présente après la mise en œuvre des nouvelles méthodes:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell_identifier";

    [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    return cell;
}

Le code que j'ai jusqu'ici fonctionne bien mais renvoie toujours le style par défaut. Comment puis-je changer cela pour pouvoir créer des cellules avec les autres styles tels que UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2 et UITableViewCellStyleSubtitle?

Je ne veux pas sous-classe UITableViewCell, je veux juste changer le type par défaut comme je pouvais le faire avant iOS 6. Il semble étrange qu'Apple fournisse des méthodes améliorées mais avec une documentation minimale pour prendre en charge leur implémentation.

Quelqu'un at-il maîtrisé cela, ou couru dans un problème similaire? J'ai du mal à trouver des informations raisonnables.

81
CaptainRedmuff

Je sais que vous avez dit que vous ne vouliez pas créer de sous-classe, mais cela semble inévitable. Sur la base du code d'assemblage lors du test dans le simulateur iOS 6.0, UITableView crée de nouvelles instances de UITableViewCell (ou ses sous-classes) en effectuant

[[<RegisteredClass> alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:<ReuseIdentifier>]

En d'autres termes, le style envoyé (UITableViewCellStyleDefault) semble être codé en dur. Pour résoudre ce problème, vous devez créer une sous-classe qui remplace le initWithStyle:reuseIdentifier: initializer par défaut et transmet le style que vous souhaitez utiliser:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    // ignore the style argument, use our own to override
    self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier];
    if (self) {
        // If you need any further customization
    }
    return self;
}

En outre, il serait peut-être préférable d'envoyer registerClass:forCellReuseIdentifier: dans viewDidLoad, au lieu de le faire chaque fois qu'une cellule est demandée:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerClass:<RegisteredClass> forCellReuseIdentifier:<ReuseIdentifier>];
}
104
bolot

dequeueReusableCellWithIdentifier n'est pas obsolète, vous n'êtes donc pas obligé d'utiliser le nouveau dequeueReusableCellWithIdentifier:forIndexPath:

Utilisez la nouvelle méthode avec la méthode de registre appropriée (dans viewDidLoad) si vous utilisez une classe de cellule personnalisée, mais utilisez l'ancienne méthode si vous souhaitez utiliser l'une des énumérations UITableViewCellStyle.

60
Murray Sagal

Vous pouvez éviter une sous-classe superflue en utilisant le générateur d'interface de storyboard:

  1. Dans la vue Storyboard, sélectionnez la cellule prototype de la cellule de la vue tableau (dans la vue tableau).
  2. Dans la vue Utilitaires, dans l'inspecteur Attributs, modifiez la valeur de style.
  3. (Facultatif) Modifier d'autres valeurs telles que Sélection et Accessoire

Le nouvel iOS 6.0 dequeueReusableCellWithIdentifier:forIndexPath: utilise ces valeurs lors de l'allocation de nouvelles cellules et de leur renvoi. (Testé sur une compilation iOS 6.0 avec Xcode 4.5.2)

11
Jeff Collier

Une autre alternative qui enregistre un fichier consiste à créer un Nib et à utiliser registerNib:forCellReuseIdentifier: à la place. 

Créer le Nib est facile: Créez un nouveau fichier .xib dans Interface Builder. Supprimer la vue par défaut. Ajoutez un objet de cellule de vue de tableau. À l'aide de l'inspecteur d'attributs, modifiez le style de la cellule. (Vous avez également la possibilité de personnaliser davantage la cellule en modifiant d’autres attributs.)

Ensuite, dans la méthode viewDidLoad de votre contrôleur de vue de table, appelez quelque chose comme:

[self.tableView registerNib:[UINib nibWithNibName:@"StyleSubtitleTableCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"Cell"];
7
Mr. Berna

La réponse de Bolot est la bonne. Simple et vous n'avez pas besoin de créer de fichier XIB.

Je voulais juste mettre à jour sa réponse pour quiconque le fait en utilisant Swift au lieu d'Objective-C:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: .value1, reuseIdentifier: reuseIdentifier)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
0
Gabriel Oliva