我遇到了一些困难,无法在其他地方找到任何解决办法,所以答案.
我在一个视图控制器中有两个表视图,它们都可以很好地来回切换,但前提是首先加载其中一个。
当我尝试先加载另一个单元时(根据用户到表的路径,有时我会这样做),应用程序崩溃时会出现错误,“无法用标识符customMessageCell去队列一个单元格--必须为标识符注册一个nib或类,或者在情节提要中连接一个原型单元格”。
我在viewDidLoad中为两个自定义单元格注册了nib,识别了故事板中的原型单元,等等。基本上,当我搜索这个错误时,所有常见的解决方案
在我的viewDidLoad中:
messageTableView.register(UINib(nibName: "CustomMessageCell", bundle: nil), forCellReuseIdentifier: "customMessageCell")
listTableView.register(UINib(nibName: "ItemCell", bundle: nil), forCellReuseIdentifier: "itemCell")另外,我有一个enum来切换表。
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时,它会立即崩溃。
有什么想法吗?
提前感谢
发布于 2019-04-19 23:51:33
如果即使每个表都已注册了相应的单元标识符,但仍会出现“无法排排单元格”错误,这意味着在为另一个表调用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。另一种方法是将每个表的UITableViewDataSource封装到自己的对象中,这样就不可能为给定的表实例化错误的单元格。它还有助于减轻视图控制器的膨胀。
https://stackoverflow.com/questions/55768648
复制相似问题