【问题标题】:UITableView - unexpectedly found nil SwiftUITableView - 意外发现 nil Swift
【发布时间】:2021-05-19 22:28:38
【问题描述】:

我有问题。我有一个表格视图,我尝试从中填充一些 firebase 数据,但我的标签有错误。 “在隐式展开可选时意外发现 nil”。在控制台中,标签显示为 nil。我已经正确连接了我的 iboutlets,并且我已经在检查器中设置了“reuseIdentifier”。我正在使用原型单元。

我的全班:

struct Info {
    var address: String
    var name: String
    var phoneNumber: String
    
}

class InfoViewController: UITableViewController
{
    let cellReuseIdentifier = "cell"
    
    var info: [Info] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        getCartProducts()
        self.tableView.register(InfoTableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        
        navigationItem.title = "Profilul meu"
        
        
        
    }
    func getCartProducts() {
        
        let db = Firestore.firestore()
        let userID = (Auth.auth().currentUser?.uid)!
        db.collection("Users").document(userID).getDocument{  (document, error) in
            if let error = error {
                print(error)
                return
            } else {
                if let  document = document {
                    let data = document.data()
                    let newEntry = Info(address: data!["address"] as! String, name: data!["name"] as! String , phoneNumber: data!["phoneNumber"] as! String
                    )
                    
        
                    self.info.append(newEntry)
                }
            }
            
            DispatchQueue.main.async {
                //  self.datas = self.filteredData
                self.tableView.reloadData()
            }
            
        }
    }
    
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return info.count
        
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! InfoTableViewCell
        let infos = info[indexPath.row]
        cell.numeL.text = infos.name
        cell.adresaL.text = infos.address
        cell.telefonL.text = infos.phoneNumber
        
        return cell
    }
    
    
    
    

}

还有我的 Cell 课程,如果这也有帮助的话:

class InfoTableViewCell: UITableViewCell {

    
    @IBOutlet weak var adresaL: UILabel!
    @IBOutlet weak var numeL: UILabel!
    @IBOutlet weak var telefonL: 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
    }

}

错误在:

 cell.numeL.text = infos.name
        cell.adresaL.text = infos.address
        cell.telefonL.text = infos.phoneNumber

【问题讨论】:

  • 使用!as! 解包本质上是危险的,并且可能导致此崩溃。查看您使用它的所有地方并学习使用if letguard let(“可选绑定”)来处理您可能拥有nil 值的情况。 docs.swift.org/swift-book/LanguageGuide/TheBasics.html
  • 在 Firebase 闭包中不需要DispatchQueue.main.async {; UI 调用总是在主线程上完成。在从 firebase 加载数据并刷新 tableView 之前,也要这样做self.tableView.register(InfoTableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)

标签: swift firebase uitableview


【解决方案1】:

如果您使用原型单元格,则必须没有 tableView.register 代码。删除它。

仔细检查情节提要中的表格视图控制器检查器。确保它具有正确的类。

然后在情节提要中检查其原型单元检查器。确保它具有正确的类。然后确保它有正确的标签出口。

【讨论】:

  • 它有正确的类并且单元格的身份检查器也是正确的。真的不知道怎么了。。
【解决方案2】:

代替

let newEntry = Info(address: data!["address"] as! String, name: data!["name"] as! String , phoneNumber: data!["phoneNumber"] as! String)

你必须使用这样的东西

guard let address = data?["address"] as? String else {return}
guard let  name = data?["name"] as? String else {return}
guard let phoneNumber = data?["phoneNumber"] as? String else {return}
let newEntry = Info(address: address, name: name , phoneNumber: phoneNumber)

此方法将安全地解包您的数据,但请记住,如果它们中的每一个都为 null,您将没有任何数据,因此最好在 firebase 数据库中设置默认值以避免该问题

也适用于您的表格视图功能 而不是

let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! InfoTableViewCell

使用

 guard let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as? InfoTableViewCell else {return UITableViewCell()}

在这种情况下,您的单元格标识符不正确,您的应用至少不会崩溃

【讨论】:

    【解决方案3】:

    您需要正确注册单元格

    self.tableView.register(UINib(nibName:"InfoTableViewCell", bundle: nil), forCellReuseIdentifier: cellReuseIdentifier)
    

    在此处设置标识符

    【讨论】:

    • 感谢您的回答,使用您的代码时出现以下错误:无法在捆绑中加载 NIB:
    • 你有InfoTableViewCell.xib 吗?还是表格内的单元格?如果在表格内,则完全删除寄存器行
    • 我正在使用原型单元。我试图删除注册行,但出现错误:“无法将具有标识符单元格的单元格出列 - 必须为标识符注册一个 nib 或一个类”
    • 已设置,但仍然出现错误,单元类也设置正确
    【解决方案4】:

    我已经解决了这个问题。我使用了一个 .xib 文件,现在正在工作。真的不知道为什么它不适用于原型单元。

    【讨论】:

      猜你喜欢
      • 2014-09-10
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-09
      • 2020-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多