web-dev-qa-db-fra.com

Impossible de retirer une cellule avec l'identifiant Cell - doit enregistrer une pointe ou une classe pour l'identifiant ou connecter une cellule prototype dans un storyboard?

J'essaie d'afficher une TableView d'une liste de chansons dans la bibliothèque d'un utilisateur. J'ai utilisé le code de ce tutoriel l (qui utilise un storyboard, mais je voudrais l'essayer d'une manière différente et avec juste une sous-classe de UITableView).

Je reçois l'erreur:

*** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit/UIKit-2903.23/UITableView.m:5261
2014-05-07 20:28:55.722 Music App[9629:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

et une erreur Thread 1: SIGABRT sur la ligne:

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

Voici mon code:

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
    NSArray *songs = [songsQuery items];

    return [songs count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...

    MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
    NSArray *songs = [songsQuery items];

    MPMediaItem *rowItem = [songs objectAtIndex:indexPath.row];

    cell.textLabel.text = [rowItem valueForProperty:MPMediaItemPropertyTitle];
    cell.detailTextLabel.text = [rowItem valueForProperty:MPMediaItemPropertyArtist];

    cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Table-view-background.png"]];
    cell.textLabel.textColor = [UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0];

    cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Table-view-selected-background.png"]];

    cell.textLabel.backgroundColor = [UIColor clearColor];
    cell.detailTextLabel.backgroundColor = [UIColor clearColor];

    return cell;
}

L'application se charge et fonctionne correctement, affichant une table vierge lorsque je l'exécute dans le simulateur iPhone sur mon Mac. il présente cette erreur lorsque je l'exécute sur mon iPhone.

Toute aide serait très appréciée, merci!

17
user3127576

Si vous créez la vue de table par programme et que vous utilisez simplement le UITableViewCell par défaut, vous devez enregistrer la classe (dans viewDidLoad est un bon endroit). Vous pouvez également le faire pour une classe personnalisée, mais uniquement si vous créez la cellule (et ses sous-vues) dans le code (utilisez registerNib: forCellWithReuseIdentifier: si la cellule est créée dans un fichier xib).

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

Cependant, cela ne vous donnera qu'une cellule de vue de tableau "de base" sans detailTextLabel. Pour obtenir ce type de cellule, vous devez utiliser la méthode de retrait la plus courte, dequeueReusableCellWithIdentifier :, qui ne lève pas d'exception si elle ne trouve pas de cellule avec cet identifiant, puis avoir une clause if (cell == nil) pour créer la cellule,

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

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    //Configure cell
   return cell;
}
33
rdelmar

S'il vous plaît, si vous utilisez une classe personnalisée pour votre cellule vérifiez que vous avez déjà enregistré la pointe pour la cellule à utiliser dans votre vue de table, comme suit:

[self.yourTableViewName registerNib:[UINib nibWithNibName:@"YourNibName" bundle:nil]
         forCellWithReuseIdentifier:@"YourIdentifierForCell"];

En dehors de cela, veuillez vérifier que votre sous-classe UITableViewCell personnalisée possède l'identifiant de réutilisation approprié.

Si vous n'utilisez pas de classe personnalisée , veuillez suivre ces instructions de Apple Docs:

La source de données, dans son implémentation de la méthode tableView: cellForRowAtIndexPath:, renvoie un objet cellule configuré que la vue de table peut utiliser pour tracer une ligne. Pour des raisons de performances, la source de données essaie de réutiliser autant que possible les cellules. Il demande d'abord à la vue de table un objet de cellule réutilisable spécifique en lui envoyant un dequeueReusableCellWithIdentifier:

Pour des informations complètes, veuillez consulter ce lien: Création d'une vue de table par programme .

J'espère que ça aide!

19
Barbara R

La raison de l'accident est que vous utilisez

[tableView dequeueReusableCellWithIdentifier: forIndexPath:]

ce qui entraînera un plantage, sauf si vous spécifiez une cellule ou un fichier nib à utiliser pour la cellule.

Pour éviter le plantage, utilisez plutôt la ligne de code suivante

[tableView dequeueReusableCellWithIdentifier:];

Cette ligne de code retournera nil si aucune cellule ne peut être utilisée.

Vous pouvez voir la différence dans les documents qui peuvent être trouvés ici .

Il y a aussi une bonne réponse à une Q&R qui peut être trouvée ici

11
Fernando

Je sais que c'est un peu tard pour répondre à cette question mais voici ce qui me manquait.

Je faisais:

let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)

Mais je devrais faire ça:

let cell = self.tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)

Remarque: le self. ajouté à côté de tableView. J'espère que cela vous fait gagner 24 heures.

3
Jsonras

si vous utilisez UITableViewCell par défaut (sans en personnaliser un) [tableView dequeueReusableCellWithIdentifier: forIndexPath:], vous devez enregistrerClass ou registerNib; (dequeReusableCellIdentifier: forIndexPath ne renverra aucune cellule, si la cellule n'est pas là, il créera automatiquement une nouvelle tableViewCell avec la valeur par défaut UITableViewCellStyelDefault!)

sinon, vous pouvez utiliser [tableView dequeueReusableCellWithIdentifier] sans registerClass ou registerNib

2
Rachel

Si vous utilisez StoryBoard, sélectionnez cette tableviewcontroller-> table-> Cell, attribuez à cette cellule un 'identifiant' dans l'inspecteur d'attributs. Assurez-vous d'utiliser le même "identifiant" dans la méthode "cellforrowatindexpath".

0
Kazmi