Swift. Proper initialization of UITableViewCell hierarchy

前端 未结 2 1865
一生所求
一生所求 2021-02-05 16:04

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

Hello. Please imagine hierarchy above. In my code I don\'t have objects exactly of type gener

相关标签:
2条回答
  • 2021-02-05 16:21

    I'm not sure I understand your question correctly, but it seems to be about inheritance between classes. So basically you have a "GenericCell" class that inherits from "UITableViewCell", and "CellOne", "CellTwo", and "CellThree" classes that each inherit from "GenericCell". If you want to go through init with style, one way to set this up would be like this:

    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)
        }
    }
    

    You could then create instances of CellOne in your table view's data source like so:

    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!
    }
    

    For each instance it will now first go through the common setup done in "GenericCell", and then through the unique setup in "CellOne". "CellTwo" and "CellThree" would be set up accordingly.

    EDIT

    A more concrete example of how to configure instances of all three Cell types:

    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!
        }
    
    0 讨论(0)
  • 2021-02-05 16:28

    This is how I would lay down the hierarchy mentioned by you:

    Step 1 : Make Generic Cell class

    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)
        }
    }
    

    Step 2 : Make Specific Cell 1 class:

    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)
        }
    }
    

    Step 3 : Make Specific Cell 2 class:

    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)
        }
    }
    

    Step 4 : Make Specific Cell 3 class:

    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)
        }
    }
    

    Step 5 : Finally use the cells like this:

    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: This would guarantee setting the properties in generic cell as well in specific cells.

    EDIT: This is how you would use cells in 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
        }
    }
    
    0 讨论(0)
提交回复
热议问题