【问题标题】:'required' initializer 'init(coder:)' must be provided by subclass of 'UITableViewCell'`'必需的'初始化程序'init(coder :)'必须由'UITableViewCell'的子类提供`
【发布时间】:2014-11-22 17:56:12
【问题描述】:

据报道,此代码在 herehere 有效,但我似乎无法使其有效。

IBOutlets 与故事板中的对象相关联。 prototypeCell 被命名,所以我可以将它与dequeueReusableCellWithIdentifier 一起使用,它的自定义类属性设置为commentCell

第一个错误(我可以解决,但上面的链接都不需要它,这让我觉得我做错了什么。我是对的吗?):

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

第二个错误(有趣的错误):

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

单元类代码:

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

初始化代码:

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
}

【问题讨论】:

    标签: ios uitableview swift


    【解决方案1】:

    第一个初始化器的正确签名是这样的:

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

    注意reuseIdentifierOptional,如? 所示。

    如果您覆盖任何类的指定初始化程序,则不会继承任何其他指定初始化程序。但是UIView 采用了NSCoding 协议,它需要一个init(coder:) 初始化器。所以你也必须实现它:

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

    但是请注意,除了调用 super 之外,您实际上并没有在任何一个初始化程序中做任何事情,因此您不需要实现任何一个初始化程序!如果你不重写任何指定的初始化器,你会继承你的超类的所有指定的初始化器。

    所以我的建议是,您只需完全删除您的 init(style:reuseIdentifier:) 初始化程序,除非您要为其添加一些初始化程序。

    如果您打算为其添加一些初始化,请注意情节提要中的原型单元init(style:reuseIdentifier:) 初始化。它们由init(coder:) 初始化。

    【讨论】:

    • 你猜到为什么var cell = self.tableView.dequeueReusableCellWithIdentifier("prototypeCell") as commentCell 会在 LLBD 中抛出错误吗?
    • 那么,您将如何在 init(coder) 方法中为 authorLabel 设置默认文本?如果我尝试这样做,我会得到一个异常(“致命错误:在展开可选值时意外发现 nil”)。我猜它不会被 super 初始化,而且还没有从情节提要中取出。那么,我应该在哪里以及如何做呢?
    • 即使你不重写指定的初始化器,如果你创建一个新的指定初始化器,子类也会丢失继承的初始化器,对吗?
    【解决方案2】:

    如果您使用带有原型单元格的情节提要,不确定为什么需要自定义 UITableViewCell 类。您可以将标签和文本视图放入单元格并使用它们。

    如果您使用的是 xib,那么我明白了,但您只需要:

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

    然后,您将在 TableView 类中注册 xib:

    override func viewDidLoad() {
            super.viewDidLoad()
    
            self.tableView.registerNib(UINib(nibName: "commentCell", bundle: nil),
                forCellReuseIdentifier: "reuseIdentifier")
        }
    

    关于 cellForRowAtIndexPath 函数,语法现在稍作修改:

    func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    
     var cell = self.tableView.dequeueReusableCellWithIdentifier("prototypeCell") as commentCell
    
    
    
            return cell
        }
    

    如果您想发布到 github,我们可以帮助进行修改。不看更多代码很难具体说明。

    【讨论】:

    • Connection "commentLabel" cannot have a prototype object as its destination.,这就是为什么
    • 有很多原因你可能想要子类化任何 UI 类,但没用
    【解决方案3】:

    Swift 4 中继承 UITableViewCell 的正确方法:

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

    【讨论】:

      【解决方案4】:

      斯威夫特 4

      按照它的建议实现required init,并在您要添加的自定义初始化程序中添加super.init(nibName: nil, bundle: nil)

      例如:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多