web-dev-qa-db-fra.com

Rapide. Initialisation correcte de la hiérarchie UITableViewCell

[UITableViewCell] <- [genericCell] <- [Cell1], [Cell2], [Cell3]

Bonjour. S'il vous plaît, imaginez la hiérarchie ci-dessus. Dans mon code, je n'ai pas exactement d'objets de type genericCell, mais cette classe partage certaines propriétés.

Quelle conception des inits devrait être dans mon code? J'ai la structure suivante pour genericCell:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    //my stuff (initializing shared properties)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

}

Mais qu'en est-il de Cell1? Comment puis-je appeler init(style: UITableViewCellStyle, reuseIdentifier: String?) dans genericCell pour les opérations "mon matériel" via l'initialisation de l'instance Cell1? Maintenant, ils ne jouent pas.


MODIFIER

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let typeOfCell = FbDataManager.sharedInstance.posts[indexPath.row][FbDataManager.sharedInstance.typeParameter] as! String

        switch typeOfCell {
            case self.linkTypeOfPost:

                var cell = tableView.dequeueReusableCellWithIdentifier(self.linkCellIdentifier) as? FbLinkPostViewCell
                if cell == nil {
                    cell = FbLinkPostViewCell.init(style: .Default, reuseIdentifier: self.linkCellIdentifier)
                }
//...

Re-bonjour. Cela fait partie du délégué de tableView, d'ailleurs j'ai copié-collé les inits d'Abhinav dans mon code et là encore ces inits ne fonctionnent pas. (pas de sortie à la console)

8
drewpts

Je ne suis pas sûr de bien comprendre votre question, mais cela semble concerner l'héritage entre les classes. Donc, fondamentalement, vous avez une classe "GenericCell" qui hérite des classes "UITableViewCell", "CellOne", "CellTwo" et "CellThree" qui héritent chacune de "GenericCell". Si vous voulez utiliser init avec style, une façon de le configurer serait la suivante:

class GenericCell: UITableViewCell {
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        // code common to all your cells goes here
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

class CellOne: GenericCell {
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier) // the common code is executed in this super call
        // code unique to CellOne goes here
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

Vous pouvez ensuite créer des instances de CellOne dans la source de données de votre vue table de la manière suivante:

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

    var cell = tableView.dequeueReusableCellWithIdentifier("cell")
    if (cell == nil) {
        cell = CellOne.init(style: .Default, reuseIdentifier: "cell")
    }
    return cell!
}

Pour chaque instance, il passe maintenant d'abord par la configuration commune effectuée dans "GenericCell", puis par la configuration unique dans "CellOne". "CellTwo" et "CellThree" seraient configurés en conséquence.

MODIFIER

Un exemple plus concret de la façon de configurer des instances des trois types de cellules:

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

        // you need to write a method like this to figure out which type you need:
        let cellID = self.cellIDForIndexPath(indexPath) // returns either "cell1", "cell2" or "cell3"

        // dequeue or init a cell of the approriate type
        var cell = tableView.dequeueReusableCellWithIdentifier(cellID)
        if (cell == nil) {
            switch cellID {
                case "cell1": cell = CellOne.init(style: .Default, reuseIdentifier: "cell")
                case "cell2": cell = CellTwo.init(style: .Default, reuseIdentifier: "cell")
                case "cell3": cell = CellThree.init(style: .Default, reuseIdentifier: "cell")
                default: cell = UITableViewCell()
            }

        }

        // configure the individual cell if needed (you need to implement methods + logic here that fit your data)
        (cell as! GenericCell).configureForData(self.dataForIndexPath(indexPath))

        return cell!
    }
12
Gamma

Voici comment je définirais la hiérarchie que vous avez mentionnée:

Étape 1: Créer une classe de cellules génériques

class GenericCell : UITableViewCell {
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        print("Generic Cell Initialization Done")
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

Étape 2: Créer une classe de cellules spécifiques 1:

class MyCell1 : GenericCell {
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        print("MyCell1 Initialization Done")
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

Étape 3: Créer une classe de cellules spécifiques 2:

class MyCell2 : GenericCell {
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        print("MyCell2 Initialization Done")
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

Étape 4: Créer une classe de cellules spécifiques 3:

class MyCell3 : GenericCell {
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        print("MyCell3 Initialization Done")
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

Étape 5: Enfin, utilisez les cellules comme ceci:

let cell1 = MyCell1.init(style: UITableViewCellStyle.Default, reuseIdentifier: "cell1")
let cell2 = MyCell2.init(style: UITableViewCellStyle.Default, reuseIdentifier: "cell2")
let cell3 = MyCell3.init(style: UITableViewCellStyle.Default, reuseIdentifier: "cell3")

PS: Cela garantirait la définition des propriétés dans une cellule générique aussi bien dans des cellules spécifiques.

EDIT: Voici comment vous utiliseriez les cellules dans cellForRowAtIndexPath:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if indexPath.section == 0 {
        let cell1 = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as MyCell1

        if cell1 == nil {
            cell1 = MyCell1.init(style: UITableViewCellStyle.Default, reuseIdentifier: "cell1")
        }

        // Do your cell property setting

        return cell1
    } else if indexPath.section == 1 {
        let cell2 = tableView.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as MyCell2

        if cell2 == nil {
            cell2 = MyCell2.init(style: UITableViewCellStyle.Default, reuseIdentifier: "cell2")
        }

        // Do your cell property setting

        return cell2
    } else {
        let cell3 = tableView.dequeueReusableCellWithIdentifier("cell3", forIndexPath: indexPath) as MyCell3

        if cell3 == nil {
            cell3 = MyCell3.init(style: UITableViewCellStyle.Default, reuseIdentifier: "cell3")
        }

        // Do your cell property setting

        return cell3
    }
}
3
Abhinav