简体   繁体   中英

'required' initializer 'init(coder:)' must be provided by subclass of 'UITableViewCell'`

This code has reportedly worked here and here , but I can't seem to make it work.

The IBOutlets are hooked up to their objects in the storyboard. The prototypeCell is named so I can use it with dequeueReusableCellWithIdentifier and it's custom class attribute is set to commentCell .

First Error (which I can solve, but neither of the links above needed it, which makes me think I'm doing something wrong. Am I right?):

Overriding method with selector 'initWithStyle:reuseIdentifier:' has incompatible type '(UITableViewCellStyle, String) -> commentCell'

Second Error (the interesting error):

'required' initializer 'init(coder:)' must be provided by subclass of 'UITableViewCell'`

Cell Class Code:

class commentCell: UITableViewCell {
    @IBOutlet weak var authorLabel: UILabel!
    @IBOutlet weak var commentLabel: UITextView!

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

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

Initialization code:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    println(comments[indexPath.row])

    var cell = self.tableView.dequeueReusableCellWithIdentifier("prototypeCell") as commentCell

    cell.commentLabel.text = comments[indexPath.row]["comment"] as NSString
    cell.authorLabel.text = comments[indexPath.row]["fromid"] as NSString
    return cell
}

The correct signature for the first initializer is this:

init(style style: UITableViewCellStyle, reuseIdentifier reuseIdentifier: String?)

Notice that reuseIdentifier is an Optional , as indicated by the ? .

If you override any of a class's designated initializers, you don't inherit any other designated initializers. But UIView adopts the NSCoding protocol, which requires an init(coder:) initializer. So you must implement that one too:

init(coder decoder: NSCoder) {
    super.init(coder: decoder)
}

Note, however, that you're not actually doing anything in either initializer except calling super, so you don't need to implement either initializer! If you don't override any designated initializers, you inherit all of your superclass's designated initializers.

So my advice is that you just remove your init(style:reuseIdentifier:) initializer entirely unless you're going to add some initialization to it.

And if you're planning to add some initialization to it, be advised that prototype cells in a storyboard are not initialized by init(style:reuseIdentifier:) . They are initialized by init(coder:) .

Not sure why you need a custom UITableViewCell class if you are using storyboard with a prototype cell. You can just drop your labels and textviews into the cell and work with them.

If you are working from a xib then I get it, but you only need:

class commentCell: UITableViewCell {
    @IBOutlet weak var authorLabel: UILabel!
    @IBOutlet weak var commentLabel: UITextView!

}

You would then register the xib in the TableView class with:

override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.registerNib(UINib(nibName: "commentCell", bundle: nil),
            forCellReuseIdentifier: "reuseIdentifier")
    }

Regarding the cellForRowAtIndexPath function, the syntax is now a little modified:

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

 var cell = self.tableView.dequeueReusableCellWithIdentifier("prototypeCell") as commentCell



        return cell
    }

If you want to post to github, we can help make modifications. It's hard to be specific without seeing more of the code.

The right way to inherit UITableViewCell in Swift 4:

class MyTableViewCell: UITableViewCell
{    
    override init(style: UITableViewCellStyle, reuseIdentifier: String?)
    {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

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

Swift 4

Implement the required init as it suggests, and add super.init(nibName: nil, bundle: nil) within your custom initialiser that you are adding

For example:

init(input: ProtocolType? = nil) {
        super.init(nibName: nil, bundle: nil)
        self.input = input
}

required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM