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

先上代码

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // 下面的代码不能正确的执行。
    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是为了系统为了提高效率的一个方法。具体就是在缓冲池里面看下有没有这个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关联
  3. storyBoard的cell的关联可以写也可以不写的
  4. 没有addSubView

最后附上自己分别用Storyboard文件,xib文件,代码直接定制3种方法定制自定义Cell的Demo链接
ThreeWaysToCustomYourCell

你可能感兴趣的:(代码定制Cell(定制Cell不能正常显示及fatal error:unexpectedly found nil))