61 votes

UITableView dans Swift

Je suis coincé depuis quelques heures à ce sujet, je ne peux pas comprendre ce qui ne va pas avec cela. Cela fonctionnerait en 2 secondes dans l'Objectif C. Cela planterait juste sur la première ligne de la méthode. Cela ne donne pas un message d'erreur, mais juste la chose amusante 'Bad_Instruction'

 func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!  {
        var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Component") as UITableViewCell

        if (cell == nil) {
            cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Component")
        }

        cell.textLabel.text = "Baking Soda"
        cell.detailTextLabel.text = "1/2 cup"

        return cell
    }
 

82voto

Sulthan Points 23360

Nous allons trouver une solution sans créer des sous-classes ou des plumes

Le vrai problème est dans le fait que la Swift fait la distinction entre les objets qui peuvent être vides (nil) et les objets qui ne peuvent pas être vide. Si vous n'enregistrez pas la plume de votre identifiant, puis dequeueReusableCellWithIdentifier peut renvoyer nil.

Cela signifie que nous devons déclarer la variable comme option:

var cell : UITableViewCell?

et nous devons convertir à l'aide de as? pas as

//variable type is inferred
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell

if cell == nil {
    cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}

//we know that cell is not empty now so we use ! to force unwrapping

cell!.textLabel.text = "Baking Soda"
cell!.detailTextLabel.text = "1/2 cup"

cell!.textLabel.text = "Hello World"

return cell

64voto

matt Points 60113

Sulthan la réponse est intelligente, mais la vraie solution est: ne pas appeler à l' dequeueReusableCellWithIdentifier. Qui était votre erreur au départ.

Cette méthode est complètement dépassé, et je suis surpris qu'il n'a pas été formellement déconseillé; aucun système qui peut accueillir Swift (iOS 7 ou iOS 8) a besoin d'elle pour quelque fin que ce soit.

Au lieu de cela, appelez la méthode moderne, dequeueReusableCellWithIdentifier:forIndexPath:. Ceci a l'avantage qu' aucune options sont impliqués; vous garantis que, une cellule sera retourné. Tous les points d'interrogation et points d'exclamation tomber, vous pouvez utiliser let au lieu de var , car la cellule de l'existence est garantie, et vous vivez dans la pratique, le monde moderne.

Vous devez, si vous n'êtes pas à l'aide d'un storyboard, inscrivez la table pour cet identifiant à l'avance, l'enregistrement d'une classe ou d'une plume. Les classiques endroit pour le faire, c'est - viewDidLoad, ce qui est dès l'affichage de la table existe.

Voici un exemple d'utilisation d'une cellule personnalisé de classe:

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

// ...

override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath) as MyCell
    // no "if" - the cell is guaranteed to exist
    // ... do stuff to the cell here ...
    cell.textLabel.text = // ... whatever
    // ...
    return cell
}

Mais si vous êtes à l'aide d'un storyboard (qui la plupart des gens le font), vous n'avez même pas besoin d'enregistrer la vue de la table en viewDidLoad! Il suffit d'entrer l'identificateur de cellule dans la table de montage séquentiel et vous êtes bon pour aller avec dequeueReusableCellWithIdentifier:forIndexPath:.

18voto

aselvia Points 81

@Sulthan la réponse est sur place. Une possible modification de fonte de la cellule comme un UITableViewCell!, plutôt qu'un UITableViewCell.

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as UITableViewCell!
    if !cell {
        cell = UITableViewCell(style:.Default, reuseIdentifier: "CELL")
    }
    // setup cell without force unwrapping it
    cell.textLabel.text = "Swift"
    return cell
}

Maintenant, vous pouvez modifier la cellule variable sans la force d'ôter à chaque fois. Faites attention lorsque vous utilisez implicitement déballé options. Vous devez être certain que la valeur que vous accédez a une valeur.

Pour plus d'informations, reportez-vous à la "Implicitement Déballé Options" de la section de La Swift Langage de Programmation.

8voto

Oscar Swanros Points 2853

Essaye ça:

 func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    cell.textLabel.text = "\(indexPath.row)"

    return cell
}
 

Notez que vous devez vous inscrire UITableViewCell et votre identifiant lors de la création d’une instanciation de votre UITableView :

 tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
 

8voto

DBoyer Points 416

Voici ce que j'ai écrit pour le faire fonctionner ...

Enregistrez d'abord la cellule de la vue tableau avec la vue tableau

 self.tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "Cell")
 

Puis configurez cellForRowAtIndexPath

 func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!  {
    var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as MyTableViewCell

    cell.textLabel.text = "Cell Text"
    cell.detailTextLabel.text = "Cell Detail Text in Value 1 Style"

    return cell
}
 

J'ai ensuite défini une sous-classe de cellule personnalisée en bas du fichier (car c'est beaucoup plus facile maintenant)

 class MyTableViewCell : UITableViewCell {

    init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
    }

}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X