Comment définir UITableViewCellStyleSubtitle et dequeueReusableCell dans Swift?

Je voudrais un UITableView avec des cellules de style de subtitle qui utilisent dequeueReusableCellWithIdentifier .

Mon code Objective-C original était:

 static NSSsortingng* reuseIdentifier = @"Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; if(!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier]; } 

Après avoir recherché les quelques questions UITableView déjà sur SO, j'ai pensé à l'écrire dans Swift comme ça:

  tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell") let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell 

Mais ça ne me laisse pas dire que je veux un style de subtitlesubtitle . J'ai donc essayé ceci:

 var cell :UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell") 

Ce qui me donne une cellule de subtitlesubtitle , mais elle ne me laisse pas dequeueReusableCellWithIdentifier .

J'ai étudié un peu plus et j'ai regardé ce didacticiel video , mais il crée une subclasssubclass séparée de UITableViewCell que je suppose n'est pas nécessaire car j'ai déjà accompli ce même effet en Obj-C.

Des idées? Merci.

Gardez à l'esprit que UITableView est défini comme facultatif dans la fonction, ce qui signifie que votre déclaration de cellule initiale doit vérifier l'option dans la propriété. En outre, la cellule mise en queue renvoyée est également facultative. Par conséquent, assurez-vous d'effectuer un cast facultatif vers UITableViewCell . Ensuite, nous pouvons forcer le déballage parce que nous soaps que nous avons une cellule.

 var cell:UITableViewCell? = tableView?.dequeueReusableCellWithIdentifier(reuseIdentifier) as? UITableViewCell if (cell == nil) { cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier) } // At this point, we definitely have a cell -- either dequeued or newly created, // so let's force unwrap the optional into a UITableViewCell cell!.detailTextLabel.text = "some text" return cell 

Fondamentalement la même chose que d'autres réponses, mais je contourne traitant des -tableView:cellForRow:atIndexPath: (vous ne pouvez pas renvoyer nil de -tableView:cellForRow:atIndexPath: dans Swift) en utilisant une variable calculée:

Swift 3

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell: UITableViewCell = { guard let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell") else { // Never fails: return UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: "UITableViewCell") } return cell }() // (cell is non-optional; no need to use ?. or !) // Configure your cell: cell.textLabel?.text = "Key" cell.detailTextLabel?.text = "Value" return cell } 

Modifier:

En fait, il serait préférable de retirer la cellule en utilisant: tableView.dequeueReusableCell(withIdentifier:for:) place.

Cette dernière variante de la fonction instancie automatiquement une nouvelle cellule si personne n'est disponible pour la réutilisation (exactement ce que mon code fait explicitement ci-dessus), et ne renvoie donc jamais nil .

Juste en s'appuyant sur la réponse de memmons en nettoyant le style Swift 2 …

 let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) ?? UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier) cell.detailTextLabel?.text = "some text" return cell 

Swift 3:

 let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) ?? UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier) cell.detailTextLabel?.text = "" return cell 
 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let reuseIdentifier = "cell" var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as UITableViewCell? if (cell == nil) { cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier) } cell!.textLabel?.text = self.items[indexPath.row] cell!.detailTextLabel?.text = self.items[indexPath.row] return cell! } 

Vous pouvez utiliser une syntaxe légèrement différente de celle de memmons pour empêcher le déballage forcé:

 let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as? UITableViewCell ?? UITableViewCell(style: .Subtitle, reuseIdentifier: reuseIdentifier) cell.detailTextLabel?.text = "some text" return cell 

Ceci utilise la syntaxe XCode 6.1 7, Swift 1.2 2.0 où UITableView n'est plus optionnel.

Je vous engage à regarder ce petit UITableView-Exemple sur Github: https://github.com/YANGReal/UITableView-Swift

Ils font comme suit:

 func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let cell = tableView .dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell cell.textLabel.text = Ssortingng(format: "%i", indexPath.row+1) // set any other property of your cell here return cell } 

Parfait comme suggéré par Michael G. Emmons, mais dans Xcode 6.1 en utilisant

 if !cell { ..... 

J'ai cette erreur:

Type facultatif '@ | value UITableViewCell?' ne peut pas être utilisé comme boolean; test pour '! = nil' à la place

La syntaxe acceptée est:

 if cell == nil { ... 
 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var CellIdentifier:Ssortingng = "Cell" var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as? UITableViewCell if cell == nil { cell = UITableViewCell(style:UITableViewCellStyle(rawValue:3)!,reuseIdentifier:CellIdentifier) } return cell! } 

Celui-ci est un peu étrange. Je m'attendrais à ce que tableView exige que nous returnnions une cellule qui y était enregistrée avec un identifiant de cellule. Mais cela ne semble pas être le cas et ce qui suit rendra une cellule pour le text textLabel et detailTextLabel:

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .Subtitle, reuseIdentifier: cellId) let user = users[indexPath.row] cell.textLabel?.text = user.name cell.detailTextLabel?.text = user.email return cell } 

Depuis tableView.dequeueReusableCell(withIdentifier:, for:) returnner une cellule non-nulle, la vérification if cell == nil est toujours false. Mais j'ai trouvé une solution pour que le style par défaut devienne quel style (value1, value2 ou subtitle), car detailTextLabel la cellule de style par défaut est nil, donc vérifiez le detailTextLabel s'il est nul, puis créez une nouvelle cellule de style et donnez-la la cellule dequeue, comme:

Swift 3:

 var cell = tableView.dequeueReusableCell(withIdentifier: yourCellReuseIdentifier, for: indexPath) if cell.detailTextLabel == nil { cell = UITableViewCell(style: .value1, reuseIdentifier: repeatCellReuseIdentifier) } cell.textLabel?.text = "Title" cell.detailTextLabel?.text = "Detail" return cell 

Ça marche pour moi.

J'espère que c'est de l'aide.

Si vous n'utilisez pas votre propre cellule personnalisée. Enregistrez simplement UITableViewCell à l'aide du code. Ensuite, vous pouvez préférer le code.

Sinon, select le storyboard, select votre TableViewCell -> Goto Atsortingbute Inspector et choisissez le style souhaité comme indiqué ci-dessous.

entrez la description de l'image ici

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { var cell:UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "cell") if (cell != nil) { cell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell") } cell!.textLabel?.text = "ABC" cell!.detailTextLabel?.text = "XYZ" return cell! } 

Utilisez simplement ceci pour Swift 3:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "My Reuse Identifier", for: indexPath) cell.textLabel?.text = "Key" cell.detailTextLabel?.text = "Value" return cell }