UITableViewCell personnalisé de nib dans Swift

J'essaie de créer une cellule de vue de table personnalisée à partir d'une plume. Je fais reference à cet article ici . Je suis confronté à deux problèmes.

J'ai créé un file .xib avec un object UITableViewCell traîné dessus. J'ai créé une sous-class de UITableViewCell et l' UITableViewCell définie comme la class de la cellule et Cell comme identifiant réutilisable.

 import UIKit class CustomOneCell: UITableViewCell { @IBOutlet weak var middleLabel: UILabel! @IBOutlet weak var leftLabel: UILabel! @IBOutlet weak var rightLabel: UILabel! required init(coder aDecoder: NSCoder!) { super.init(coder: aDecoder) } override init(style: UITableViewCellStyle, reuseIdentifier: Ssortingng!) { super.init(style: style, reuseIdentifier: reuseIdentifier) } override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } } 

Dans le UITableViewController j'ai ce code,

 import UIKit class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate { var items = ["Item 1", "Item2", "Item3", "Item4"] override func viewDidLoad() { super.viewDidLoad() } // MARK: - UITableViewDataSource override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { return items.count } override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let identifier = "Cell" var cell: CustomOneCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomOneCell if cell == nil { tableView.registerNib(UINib(nibName: "CustomCellOne", bundle: nil), forCellReuseIdentifier: identifier) cell = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomOneCell } return cell } } 

Ce code ne comporte aucune erreur mais quand je l'exécute dans le simulateur, il ressemble à ceci.

entrez la description de l'image ici

Dans le UITableViewController du storyboard, je n'ai rien fait dans la cellule. Identifiant vide et aucune sous-class. J'ai essayé d'append l'identificateur de cellule à la cellule prototype et l'ai exécuté à nouveau, mais j'ai obtenu le même résultat.

Une autre erreur que j'ai rencontrée est, quand j'ai essayé d'implémenter la méthode suivante dans UITableViewController.

 override func tableView(tableView: UITableView!, willDisplayCell cell: CustomOneCell!, forRowAtIndexPath indexPath: NSIndexPath!) { cell.middleLabel.text = items[indexPath.row] cell.leftLabel.text = items[indexPath.row] cell.rightLabel.text = items[indexPath.row] } 

Comme indiqué dans l'article que j'ai mentionné j'ai changé le type de formulaire de UITableViewCell à CustomOneCell qui est ma sous-class de UITableViewCell. Mais j'ai l'erreur suivante,

Méthode de rlocation avec le sélecteur 'tableView: willDisplayCell: forRowAtIndexPath:' a un type incompatible '(UITableView !, CustomOneCell !, NSIndexPath!) -> ()'

Quelqu'un at-il une idée de la façon de résoudre ces erreurs? Ceux-ci semblaient bien fonctionner en Objective-C.

Je vous remercie.

EDIT: Je viens de remarquer que si je change l'orientation du simulateur en paysage et que je la ramène au portrait, les cellules apparaissent! Je n'arrivais toujours pas à comprendre ce qui se passait. J'ai téléchargé un projet Xcode ici démontrant le problème si vous avez le time pour un coup d'oeil rapide.

Vous devriez essayer le code suivant pour votre projet (mis à jour pour Swift 2):

CustomOneCell.swift

 import UIKit class CustomOneCell: UITableViewCell { // Link those IBOutlets with the UILabels in your .XIB file @IBOutlet weak var middleLabel: UILabel! @IBOutlet weak var leftLabel: UILabel! @IBOutlet weak var rightLabel: UILabel! } 

TableViewController.swift

 import UIKit class TableViewController: UITableViewController { let items = ["Item 1", "Item2", "Item3", "Item4"] override func viewDidLoad() { super.viewDidLoad() tableView.registerNib(UINib(nibName: "CustomOneCell", bundle: nil), forCellReuseIdentifier: "CustomCellOne") } // MARK: - UITableViewDataSource override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("CustomCellOne", forIndexPath: indexPath) as! CustomOneCell cell.middleLabel.text = items[indexPath.row] cell.leftLabel.text = items[indexPath.row] cell.rightLabel.text = items[indexPath.row] return cell } } 

L'image ci-dessous montre un set de contraintes qui fonctionnent avec le code fourni sans aucun message d'ambiguïté de contraintes de la part de Xcode.

entrez la description de l'image ici

Voici mon approche en utilisant Swift 2 et Xcode 7.3. Cet exemple utilise un seul ViewController pour charger deux files .xib: un pour UITableView et un pour UITableCellView.

entrez la description de l'image ici

Pour cet exemple, vous pouvez déposer un UITableView directement dans un file TableNib .xib vide. À l'intérieur, définissez le propriétaire du file sur votre class ViewController et utilisez une sortie pour referencer la tableView.

entrez la description de l'image ici

et

entrez la description de l'image ici

Maintenant, dans votre controller de vue, vous pouvez déléguer la tableView comme vous le feriez normalement, comme si

 class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { @IBOutlet weak var tableView: UITableView! ... override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // Table view delegate self.tableView.delegate = self self.tableView.dataSource = self ... 

Pour créer votre cellule personnalisée, encore une fois, déposez un object Table View Cell dans un file TableCellNib .xib vide. Cette fois, dans le file .xib de la cellule, vous n'avez pas besoin de spécifier un "propriétaire", mais vous devez spécifier une class personnalisée et un identificateur comme "TableCellId".

entrez la description de l'image ici entrez la description de l'image ici

Créez votre sous-class avec tous les points de vente dont vous avez besoin

 class TableCell: UITableViewCell { @IBOutlet weak var nameLabel: UILabel! } 

Enfin … de return dans votre View Controller, vous pouvez charger et afficher le tout comme si

 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // First load table nib let bundle = NSBundle(forClass: self.dynamicType) let tableNib = UINib(nibName: "TableNib", bundle: bundle) let tableNibView = tableNib.instantiateWithOwner(self, options: nil)[0] as! UIView // Then delegate the TableView self.tableView.delegate = self self.tableView.dataSource = self // Set resizable table bounds self.tableView.frame = self.view.bounds self.tableView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] // Register table cell class from nib let cellNib = UINib(nibName: "TableCellNib", bundle: bundle) self.tableView.registerNib(cellNib, forCellReuseIdentifier: self.tableCellId) // Display table with custom cells self.view.addSubview(tableNibView) } 

Le code montre comment vous pouvez simplement charger et afficher un file nib (la table), et en second lieu comment save une pointe pour l'utilisation de la cellule.

J'espère que cela t'aides!!!

Pour corriger l'erreur "Méthode de substitution … a un type incompatible …" J'ai modifié la déclaration de la fonction

 override func tableView(tableView: (UITableView!), cellForRowAtIndexPath indexPath: (NSIndexPath!)) -> UITableViewCell {...} 

(était -> UITableViewCell! – avec un point d'exclamation à la fin)

Une autre méthode qui peut fonctionner pour vous (c'est comme ça que je le fais) est d'save une class.

Supposons que vous créez un tableau personnalisé comme suit:

 class UICustomTableViewCell: UITableViewCell {...} 

Vous pouvez ensuite save cette cellule dans n'importe quel UITableViewController dans lequel vous l'affichez avec "registerClass":

 override func viewDidLoad() { super.viewDidLoad() tableView.registerClass(UICustomTableViewCell.self, forCellReuseIdentifier: "UICustomTableViewCellIdentifier") } 

Et vous pouvez l'appeler comme vous l'attendez dans la cellule pour la méthode de ligne:

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("UICustomTableViewCellIdentifier", forIndexPath: indexPath) as! UICustomTableViewCell return cell }