ios - 如何修复 Swift 中的“无法使单元格出列”错误
问题描述
我遇到了一些困难,并且无法在其他 SO 答案中找到任何解决方案......
我在一个视图控制器中有两个表视图,它们都可以很好地来回切换,但前提是首先加载其中一个。
当我尝试先加载另一个时(有时我会根据用户到表的路径来执行此操作),应用程序崩溃并出现错误“无法使具有标识符 customMessageCell 的单元格出列 - 必须注册一个 nib 或一个标识符的类或连接故事板中的原型单元“
我已经在 viewDidLoad 中为两个自定义单元格注册了笔尖,在情节提要中识别了原型单元格等。基本上,当我搜索此错误时,所有常用的解决方案
在我的 viewDidLoad 中:
messageTableView.register(UINib(nibName: "CustomMessageCell", bundle: nil), forCellReuseIdentifier: "customMessageCell")
listTableView.register(UINib(nibName: "ItemCell", bundle: nil), forCellReuseIdentifier: "itemCell")
另外,我有一个可以切换表格的枚举
switch currentTable {
case .list:
tableSelected(table: "list")
case .notes:
tableSelected(table: "notes")
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch currentTable {
case .list:
let cell = tableView.createCell(tableView: listTableView, indexPath: indexPath, itemArray: listArray)
return cell
case .notes:
let cell = tableView.dequeueReusableCell(withIdentifier: "customMessageCell", for: indexPath) as! CustomMessageCell
if messageArray.count == 0 {
cell.messageBody.text = "No notes yet"
} else {
cell.messageBody.text = messageArray[indexPath.row].messageBody
cell.senderUser.text = messageArray[indexPath.row].sender
let user = cell.senderUser.text
switch user {
case "jeffrey@sandiegomentors.com":
cell.avatarImageView.image = UIImage(named: "team-4")
case "djones219@pointloma.edu":
cell.avatarImageView.image = UIImage(named: "team-3")
case "dave@sandiegomentors.com":
cell.avatarImageView.image = UIImage(named: "team-2")
case "amirthought@gmail.com":
cell.avatarImageView.image = UIImage(named: "team-6")
case "james@sandiegomentors.com":
cell.avatarImageView.image = UIImage(named: "team-1")
default:
cell.avatarImageView.image = UIImage(named: "twitteregg")
}
if cell.senderUser.text == Auth.auth().currentUser?.email as String? {
cell.messageBackground.backgroundColor = #colorLiteral(red: 0.005996327382, green: 0.4056355059, blue: 0.8481400013, alpha: 1)
} else {
cell.messageBackground.backgroundColor = #colorLiteral(red: 0.3254587054, green: 0.325510323, blue: 0.3254474401, alpha: 1)
}
if let timeStamp = messageArray[indexPath.row].time {
let date = Date(timeIntervalSince1970: timeStamp/1000)
let formatter = DateFormatter()
formatter.dateFormat = "MMM d, yyyy"
let dateString = formatter.string(from: date)
cell.timeLabel.text = dateString
}
}
return cell
}
func tableSelected(table: String) {
if table == "list" {
listTableView.isHidden = false
messageTableView.isHidden = true
messageInputView.isHidden = true
addButton.isEnabled = true
currentTable = .list
buttonSelection(selected: tabButtons[1], unselected: tabButtons[0])
buttonTodoWidthConstraint.isActive = true
buttonNotesWidthConstraint.isActive = false
listTableView.reloadData()
} else {
messageTableView.isHidden = false
messageInputView.isHidden = false
listTableView.isHidden = true
addButton.isEnabled = false
currentTable = .notes
buttonSelection(selected: tabButtons[0], unselected: tabButtons[1])
buttonNotesWidthConstraint.isActive = true
buttonTodoWidthConstraint.isActive = false
messageTableView.reloadData()
scrollToBottom()
}
}
当我运行应用程序并将初始 currentTable 作为 .list 时,我可以在两者之间切换(通过一个切换枚举值的按钮),并且它按预期工作。
当我将初始 currentTable 作为 .notes 时,它会立即崩溃。
有任何想法吗?
提前致谢
解决方案
如果即使每个表都注册了其适当的单元格标识符,但您仍收到“无法使单元格出队”错误,这意味着您可能在为另一个表cellFor
调用时为一个表实例化了一个单元格。当您有一组UITableViewDataSource
方法为两个表提供服务时,这很容易做到。您可以通过在 中添加断点来确认这一点cellFor
,将tableView
传递给该方法的值与您的两个出口进行messageTableView
比较listTableView
: 确保您正在实例化适合该表的单元格。
我建议不要依赖,而是检查以cellFor
确定要实例化哪种类型的单元格。那么根本不可能实例化错误的单元格。你甚至可以完全消除。currentTable
tableView
currentTable
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch tableView {
case messageTableView:
...
case listTableView:
...
default:
fatalError()
}
}
坦率地说,我不鼓励将一个UITableViewDataSource
用于两个不同的表。另一种方法是将 for each 封装UITableViewDataSource
到它自己的对象中,这样就不可能为给定的表实例化错误的单元格。它还有助于缓解视图控制器膨胀。
推荐阅读
- xml - 如何使用 Xquery 和 FLOWR 迭代并返回每个结果?
- spring - Spring Data / Hibernate 使用 Postgres 保存实体,在冲突更新某些字段时使用插入
- cordova - 如何在 PhoneGap config.xml 中从 npm / github 引用 cordova-plugin
- google-chrome - Cloud-flare 通用证书上的 ERR_INVALID_CERT_AUTHORITY(怀疑是谷歌浏览器)
- javascript - 在小数点左侧填充 2 位,在右侧填充 1
- c++ - 如何定义一个可以在没有联合的情况下保存 uintptr_t 或 uint32_t 的类型?
- powershell - Powershell 无法仅将文件从一个目录移动到另一个目录?
- c++ - 有没有办法在 C++ 中创建类型变量?
- python-3.x - 如何在 python3 脚本中导入 gimp?
- javascript - 从属性值中提取一个数字