自定义的UITableviewCell中的IBOutlet始终为nil

10

我有一个自定义的UITableViewCell子类,其中包含一个用于UILabel的简单IBOutlet设置。

class SegmentCell: UITableViewCell {

    @IBOutlet weak var test: UILabel!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        test.text = "Some Text"
    }

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

}

我相信我已经正确设置了一切,按照其他答案的方法操作,但UILabel始终为nil。

视图控制器:

viewDidLoad:

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

cellForForAtIndexPath

的正确翻译应为

cellForItemAtIndexPath

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! SegmentCell
    return cell
}
  • 单元格设置为自定义
  • 重用标识符正确
  • 单元格类是SegmentCell
  • 表视图内容为动态原型

我漏掉了什么?


2
在viewDidLoad中,您不需要调用self.tableView.registerClass(SegmentCell.self,forCellReuseIdentifier:“Cell”),只需将Mainstoryboard中的prototypeCells类设置为“SegmentCell”。 - Fernando Mondo
1
我意识到这是一个非常老的问题,但它目前没有答案,我偶然遇到它,因为我遇到了类似的问题。在你的情况下,我认为weak var是关键 - 如果你的SegmentCell是唯一持有对UILabel的引用的东西,那么它不会增加保留计数,因此标签将被释放,因为没有人有强引用它。当你尝试设置.text时,它已经消失了。 - Chris
6个回答

10
由于您正在使用Xib文件,因此您需要注册。
tableView.register(UINib(nibName: "yourNib", bundle: nil), forCellReuseIdentifier: "CellFromNib")

如果只使用类注册,系统将不会知道它的Xib。对我来说,这很有效。


3
根据您注册单元格的方式,它不会从storyboard或xib文件中加载。它只会调用那个init方法。您的init方法没有创建标签,因此它将始终为nil。
您还应该使用dequeueReusableCellWithIdentifier(_:forIndexPath:)而不是dequeueReusableCellWithIdentifier(_:)。后者早于storyboard,除非您先前创建了具有该标识符的单元格并返回它,否则将返回nil。
最后,tableView调用的init方法不是您实现的方法,否则在尝试解包nil可选项时,应用程序将在test.text = ...上崩溃。

我正在故事板中创建它,在原型单元格中。 - Kyle Goslan
4
那么您就不应该在代码中将其注册到“tableView”,并且可以期望调用“init(coder:)”。 - Charles A.
1
所以我已经删除了“tableView.registerClass”,并将SegmentCell类中的init方法更改为required init?(coder aDecoder: NSCoder) {,但仍然存在相同的问题。 - Kyle Goslan
1
你不需要一个。你可以在故事板中设置那个文本。 - Charles A.
是的,我对标签进行了子类化,因为 VC 变得有点臃肿,所以我想将功能移动到它自己的类中,但是当然,单元格只会被初始化一次,然后被取消排队...也许我应该睡觉了。谢谢! - Kyle Goslan
显示剩余6条评论

1

UITableViewCell类和ContentView类不能相同。


0

你应该先在viewDidLoad函数中进行注册。

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

1
这实际上是正确的方向。但是调用是这样的:TableView.register(UINib.init(nibName: "CellXibName", bundle: nil), forCellReuseIdentifier: "CellIdentifier") - Don Miguel

0

我遇到了相同的问题,将自定义单元格类添加到在StoryBoard中放置的表视图中的单元格后。 我也像文档中那样注册了单元格。但现在我解决了我的问题。

"我取消注册并再次检查单元格,所有的IBOutlets都被初始化了"


0

我认为在初始化时基本上还没有设置插座。如果您想要访问插座并对其进行操作,则可以重写didMoveToSuperview或类似方法,并在其中执行操作。例如,这就是我必须执行的操作,以便访问单元格中的按钮插座:

open class MyTableViewCell: UITableViewCell {
    // Top stack view, not the inner one.
    @IBOutlet weak var stackView: UIStackView!
    @IBOutlet weak var buttonView: UIButton?

    open override func didMoveToSuperview() {
        buttonView?.titleLabel?.adjustsFontForContentSizeCategory = true
    }

    func adjustForAccessibilityCategory(accessible: Bool) {
        if accessible {
            stackView.axis = .vertical
            stackView.alignment = .leading
            stackView.spacing = 2
        } else {
            stackView.axis = .horizontal
            stackView.alignment = .center
            stackView.spacing = 20
        }
    }

    open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        if #available(iOS 11.0, *) {
            adjustForAccessibilityCategory(accessible: traitCollection.preferredContentSizeCategory.isAccessibilityCategory)
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接