我很遗憾再问一个"在TableViewCell中发现nil unwrapping可选"发布,但经过几个小时的调试和阅读其他此类帖子,我仍然坚持。我想我已经涵盖了所有常见的错误,但仍然无法让事情发挥作用。
作为一个起点,只要我在单元格中使用默认标签,一切都正常,用" cell.textLabel!.text = mystring引用。"我有另一个案例,我用图像和标签定制原型单元格,这也很好。
在目前的情况下,我有一个普通的UIViewController,其他一些视图和一个UITableView嵌入。普通的UIViewController被设置为单元格的委托。
这里是SettingsCell.swift代码。很简单。 xcode中Outlet左侧的小点是实心的,表明插座已正确连接到原型表格单元格上的CellTwo标签。
class SettingsCell: UITableViewCell {
@IBOutlet weak var CellTwo: UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier reuseID: String?) {
super.init(style: style, reuseIdentifier: reuseID)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
在相应的SettingsVC.swift视图控制器中,这里是dequeueCell代码,它在尝试设置cell.CellTwo值时采用nil错误。
单元格在表格视图中显示正常,但只显示属于UILabel的默认textLabel.txt。我的自定义标签根本没有显示。
func tableView(
tv: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tv.dequeueReusableCellWithIdentifier("SettingsCell") as! SettingsCell
let row = indexPath.row
cell.textLabel!.text = SettingsNames[row]
// the commented out line below crashes on a nil unwrapped optional
// cell.CellTwo!.text = "Blah"
if let b = cell.CellTwo {
b.text = "Blah"
}
return cell
}
用小"让b ="可选的展开零保护,应用程序不会崩溃,但我的第二个标签也没有设置。最后,考虑注册课程。
网上有许多例子(不使用原型)你注册课程,我在成功之前已经完成了。我已经做了一个例子,我建立了一个自定义原型单元,而且那个也工作得很好。但是......我认为所有这些示例都使用的是UITableViewController,而不是普通的UIViewController +嵌入式UITableView。也许这与它有关。
无论如何,这里是包含UITableView的UIViewController中的init / viewDidLoad代码。从代码中可以看出,UIViewController声明了数据源和委托职责,果然,表行显示并正常工作。
我尝试过双向注册 - 没有代码注册,也没有代码注册行。但它根本没有任何区别 - 我的代码仍然在单元格中对我的自定义标签的nil引用中崩溃。
class SettingsVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
SettingsTV.dataSource = self
SettingsTV.delegate = self
// I tried with this line in and out, no difference, the crash still happens
//SettingsTV.registerClass(SettingsCell.self, forCellReuseIdentifier: "SettingsCell")
SettingsTV.estimatedRowHeight = 70
}
我的自定义标签不会以某种方式创建或初始化。但我无法解释。有任何想法吗?感谢
答案 0 :(得分:0)
我的问题的答案是在上面第一段代码中显示的SettingsCell的初始化中。该初始化序列是从一个工作正常的例子中复制的,但是没有使用故事板。相反,该示例仅限于使用UITableViewCell定义中的默认textLabel.text字段。
为了解决这个问题,我只是不断回过我的例子,试图在已经有效的例子中重新创建问题。这是关键。
如果您将故事板与原型单元格一起使用,则表单元格初始化看起来不像这个帖子中的第一个块!这种风格仅适用于非故事板细胞。
相反,它应该如下所示。请注意,我注释掉了xcode在创建时插入文件的默认代码。因此,只要你有奥特莱斯的地方,你基本上可以有一个空的类。
class SettingsCell: UITableViewCell {
@IBOutlet weak var XXXLabel: UILabel!
@IBOutlet weak var CellTwo: UILabel!
// override func awakeFromNib() {
// super.awakeFromNib()
// // Initialization code
// }
//
// override func setSelected(selected: Bool, animated: Bool) {
// super.setSelected(selected, animated: animated)
//
// // Configure the view for the selected state
// }
}
第二件事是故事板上的两个标签放在任意大小的故事板的两端。我的约束使右手标签脱离模拟设备的边缘。我碰巧在模拟器中旋转设备,然后!有第二个标签。我应该更经常地使用预览器。 : - )
答案 1 :(得分:0)
您是否尝试在单独的XIB中定义自定义单元格而不是在tableview中使用原型单元格?它与您所做的几乎完全相同,但它只有故事板中的另一个XIB文件。要创建XIB:
档案 - >新文件 - > iOS - >用户界面 - >清空 将UITableViewCell拖到XIB并相应地进行自定义。将其类设置为SettingsCell并将标签等连接到您的SettingsCell类
然后在你的VC中注册它:
let nibName = UINib(nibName: "SettingsCell", bundle:nil)
self.SettingsTV.registerNib(nibName, forCellReuseIdentifier: "SettingsCell")
答案 2 :(得分:0)
答案的另一部分是在本文顶部显示的NSCoder所需的init块的内容。该块是从一个没有使用故事板原型单元的工作示例中复制的。所以当我用原型tableview单元尝试时,我经常会遇到致命的错误。
如果您正在使用原型单元格,那么该块应该是什么样子(必须)。所需的NSCoder必须调用super.init,如下所示:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//fatalError("init(coder:) has not been implemented")
}
奇怪的是,当xcode通过注入模板NSCoder所需的init来自动修复NSCoder问题时?函数,它会注入一个会破坏原型单元格的函数。为什么不添加super.init(..)行而不是致命错误行?可能有一个原因,但不是我能看到的原因。
无论如何,所有这些对我来说现在都适用,即使是原型故事板表视图。所以我认为这就解决了所有问题/问题。