代碼定制Cell(定制Cell不能正常顯示及fatal error:unexpectedly found nil)

先上代碼

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // 下面的代碼不能正確的執(zhí)行。
    let cell = tableView.dequeueReusableCell(withIdentifier: "CellIDForCodeCustomCell", for: indexPath) as! CodeCustomCell
    // Configure the cell...
    cell.configure(modelData: (modelData?[indexPath.row])!) // fatal error: unexpectedly found nil while unwrapping an Optional value
    return cell
}

兩個錯誤:

1. fatal error: unexpectedly found nil while unwrapping an Optional value(一開始的錯誤注冊后解決)
2. 即使注冊了cell之后,View還是不能正確顯示我自己自定義的cell

上面的代碼不能正常工作。知道的是:

  1. dequeueReusableCell是為了系統(tǒng)為了提高效率的一個方法。具體就是在緩沖池里面看下有沒有這個Cell。沒有的話再初始化它這樣。
  2. 后面的代碼運行沒有問題。
  3. 然后看了幾篇相關的文章。貌似意思是說dequeueReusableCell除了在緩沖池里面找東西還做了點別的?
  4. Swift中的構造器解釋init和自定義cell的問題
  5. 《重寫prepareForReuse來重用UITableViewCell》-Cell重用的問題

引用下第一篇文章的話:

  1. 指定構造器必須調用它直接父類的指定構造器方法.
  1. 便利構造器必須調用同一個類中定義的其它初始化方法.
  2. 便利構造器在最后必須調用一個指定構造器.

引用下《重寫prepareForReuse來重用UITableViewCell》的話:

重用cell的機制是利用緩沖池,將可重用的cell保存起來,顯示cell時,先從緩沖池中取,如果緩沖池中沒有此類的cell,也就是沒有可重用的cell,此時就會重新初始化一份cell,并且加到緩沖池中。

最終問題得以解決,涉及這幾個問題:

  1. 一個是Swift的幾個init構造器的關系的問題上面的第4個就是對應的解析
  2. 另一個就是官方文檔中強調的要注冊的問題。

貼上修改后的代碼。

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.register(CodeCustomCell.self, forCellReuseIdentifier: "CellIDForCodeCustomCell")
    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false
    
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CellIDForCodeCustomCell", for: indexPath) as UITableViewCell
    // Configure the cell...
    (cell as! CodeCustomCell).configure(modelData: (modelData![indexPath.row])!)
    return cell
}
class CodeCustomCell: UITableViewCell{
    var _imageView:UIImageView!
    var label1:UILabel!
    var label2:UILabel!
    var label3:UILabel!
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        _imageView = UIImageView(frame: CGRect(x: 50, y: 0, width: 88, height: 88))
        label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 42, height: 21))
        label2 = UILabel(frame: CGRect(x: 0, y: 29, width: 42, height: 21))
        label3 = UILabel(frame: CGRect(x: 0, y: 58, width: 42, height: 21))
    }
    
    func configure(modelData:ModelData){
        label1.text = modelData.attr1
        label2.text = modelData.attr2
        label3.text = modelData.attr3
        _imageView.image = UIImage(named: modelData.imageName)
        self.addSubview(label1)
        self.addSubview(label2)
        self.addSubview(label3)
        self.addSubview(_imageView)
    }
    
    required init?(coder aDecoder: NSCoder) {
        // super.init(style: .default, reuseIdentifier: "CellIDForCodeCustomCell")
        fatalError("init(coder:) has not been implemented")
    }
}

順帶說說其他沒能正常顯示的原因:

  1. dataSource,delegate沒有設置
  2. storyBoard沒有和當前TableViewController關聯(lián)
  3. storyBoard的cell的關聯(lián)可以寫也可以不寫的
  4. 沒有addSubView

最后附上自己分別用Storyboard文件,xib文件,代碼直接定制3種方法定制自定義Cell的Demo鏈接
ThreeWaysToCustomYourCell

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容