【问题标题】:Custom table view cell: IBOutlet label is nil自定义表格视图单元格:IBOutlet 标签为 nil
【发布时间】:2015-05-19 23:45:51
【问题描述】:

考虑以下简单的视图控制器:

class ViewController: UIViewController, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!

    var items = ["One", "Two", "Three"]

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "customCell")
        self.tableView.dataSource = self
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.items.count;
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("customCell") as CustomTableViewCell
        cell.titleLabel!.text = self.items[indexPath.row]
        return cell
    }
}

以及自定义单元格视图:

class CustomTableViewCell: UITableViewCell {
    @IBOutlet weak var titleLabel: UILabel!   
}

此代码导致以下错误。

致命错误:在展开可选值时意外发现 nil

titleLabel 为零 - 不清楚原因。设置UITableViewCell(如textLabel)的默认属性就可以了。

我正在为自定义单元格使用笔尖。

标签和表格视图都正确连接到它们的IBOutlets。

原型单元格和自定义 nib 视图都被标记为具有 CustomTableViewCell 类。

我是 iOS 开发新手,我是否遗漏了一些明显的东西?

Sample Xcode project available.

【问题讨论】:

  • 这里的单元格不是零吗? (let cell = self.tableView.dequeueReusableCellWithIdentifier("customCell") as CustomTableViewCell)
  • 您注意到警告“/Main.storyboard:64: Prototype table cells must have reuse identifiers”?
  • @ThomasKilian 在属性检查器中添加重用标识符会删除警告,但不会影响问题。
  • @iOSfleer cell 不为零。例如,设置单元格的 textLabel 属性会导致标签正确显示在 UI 中。
  • 如果您在 xib 文件中创建了单元格,则应注册 nib,而不是类(仅当单元格的子视图是在代码中创建时才注册类)。

标签: ios uitableview swift interface-builder


【解决方案1】:

像这样注册你的笔尖:

let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: "PickerCell", bundle: bundle)
collectionViewPicker.register(nib, forCellWithReuseIdentifier: "cell")

【讨论】:

  • 它对我来说也很好用。你必须使用你的 tableView 对象而不是 collectionViewPicker!
【解决方案2】:

请确保您在 viewdidload 中注册您的 nib(自定义单元格)时没有犯任何错误。笔尖名称和reuseIdentifiers应该不会错。

【讨论】:

    【解决方案3】:

    在没有 !

    的情况下为我工作

    编辑

        let challenge = self.challenges![indexPath.row]
    
        let title = challenge["name"]
        if title != nil {
            cell.titleLabel.text = title
        }
    

    【讨论】:

    • title 是什么?显然只检查 nil 就可以了,但这完全绕过了这个问题。
    • 这只是一个示例,我编辑了我的帖子以了解。
    【解决方案4】:

    首先,您使用 nib 文件将自定义单元格加载到表格中。如果您是 Swift/Cocoa 的新手,这可能会更令人头疼。我暂时将所有内容移至情节提要。不要使用 nib 文件单击,而是转到 Storyboard,单击您的 UITableView 并确保 TableView 的内容设置为 Dyanamic Prototypes

    接下来,单击原型单元格(表格视图中的唯一一个)并将类设置为CustomTableViewCell,并将其重用标识符设置为customCell

    接下来,将标签添加到原型单元格并将其链接到 CustomTableViewCell 类中的 IBOutlet。只要您在情节提要中设置了重用标识符,您就不需要注册您的customCell。删除这一行:

    self.tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "customCell")
    

    它应该运行。

    【讨论】:

    • 我已经注释掉了那行,问题仍然存在。 (没有警告,并且在属性检查器中正确设置了重用标识符)
    • 哦,我明白了,您正在为您的 CustomViewCell 使用笔尖。您需要在它具有误导性的问题上提及这一点。你有什么理由不只是在情节提要中生成单元格吗?
    • 我正在编写“寄存器”并设置重用 ID 故事板。这始终返回自定义单元格的 NIL 属性(例如,“label”、“imageview”等)。当我删除寄存器编码时,它按预期工作。
    • 这里的关键是将情节提要上的单元格视图与重用标识符链接并删除行collectionView.register(...)
    • 这不是一个好的答案,因为它没有回答问题。我不想知道如何做到这一点。我想知道如何按照提问者的方式去做,而不是被告知“这是个坏主意,因为我是 Swift 新手。”我不在乎那个。当他们不回答问题时,谁会检查这些东西?
    【解决方案5】:

    试试这个

    import UIKit
    
    class ViewController: UIViewController, UITableViewDataSource {
        @IBOutlet weak var tableView: UITableView!
    
        var items = ["One", "Two", "Three"]
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.tableView.registerNib(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "customCell")// CustomTableViewCell.self, forCellReuseIdentifier: "customCell")
            self.tableView.dataSource = self
        }
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return self.items.count;
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = self.tableView.dequeueReusableCellWithIdentifier("customCell", forIndexPath: indexPath) as CustomTableViewCell
            cell.titleLabel!.text = self.items[indexPath.row]
            return cell
        }
    }
    

    【讨论】:

    • 这似乎是个问题。谢谢。
    • 这是显而易见的答案。由于您是在 Nib 上构建单元,因此您必须使用适当的方法注册该单元。 registerNib 而不是 registerClass...
    • 寻找这个解决方案已经好几个小时了
    • 这是正确的答案。它直接解决了发布者的问题。
    【解决方案6】:

    您应该使用dequeueReusableCellWithIdentifier:forIndexPath 将单元格出列。

    如果您使用故事板创建单元格,则不需要注册类以供重用,因为如果您设置了重用标识符,故事板会为您完成。

    【讨论】:

    • 这并不能解决问题,同样的问题。我已根据您的建议更新了问题中的示例 XCode 项目。
    • 你有self.tableView.delegate = self吗? viewDidLoad 中似乎不见了?您分配了 dataSource 委托而不是委托?
    • 刚刚查看了您的来源。如上所述,您没有委托,也没有 heightForRowAtIndexPath 等方法……这无济于事。
    • 我尝试从我的主项目中提取可以复制问题的最小代码子集。在我的实际项目中,我确实有其余的管道——是否有任何迹象表明这些东西导致了问题?它们出现在我的主要项目中。
    • 如果它们存在于主代码中,则不会。才发现他们不见了。如果您从 IBOutlet 中删除“弱”语句,只有其他建议会发生什么?
    猜你喜欢
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多