在 iOS 8.3 上注册 Nib/Class 单元格崩溃

Register Nib/Class cell crash on iOS 8.3

我在 viewDidLoad 中使用了以下代码来注册 nib 单元格:

tableView.register(UINib(nibName: "ShoppingViewCell", bundle: Bundle.main), forCellReuseIdentifier: "ShoppingViewCell")

cellForRowAtIndexPath 中,我将以下内容用于单元格:

let cell = self.tableView.dequeueReusableCell(withIdentifier: "ShoppingViewCell", for: indexPath) as! ShoppingViewCell

return cell

但遗憾的是,这仅适用于 IOS 9 及更高版本,尝试 运行 iOS 8.3 上的此代码崩溃并出现以下错误:

2016-09-27 14:17:04.859 Tazaj[29070:1917376] *** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-3347.44/UITableView.m:6245
2016-09-27 14:17:04.877 Tazaj[29070:1917376] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier ShoppingViewCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

自从 iOS 5/6 以来已经找到了 register nib 和 dequeueReusableCell,为什么它不能在 iOS 8.3 上工作。

我知道 运行 在 cellForRowAtIndex 中使用以下代码可以解决问题:

    var mycell = tableView.dequeueReusableCell(withIdentifier: "ShoppingViewCell") as? ShoppingViewCell

    if (mycell == nil) {

        mycell = Bundle.main.loadNibNamed("ShoppingViewCell", owner: nil, options: nil)?.last as? ShoppingViewCell

    }

但是我构建了一个完整的项目而没有检查 cell 是否为 nil。我的意思是我该如何解决这个问题?因为苹果说注册单元格并按照你想要的方式使用单元格,所以我做到了。那么为什么只在 iOS 8.x/8.3 它不能工作?

如何在每个 cellForRowAtIndexPath 中用最少的替换代码块 ignore/fix 那个错误?

只需将此方法放入您的自定义单元格中即可 class

class func cellForTableView(tableView: UITableView, atIndexPath indexPath: NSIndexPath) -> ShoppingViewCell {
    let kShoppingViewCellIdentifier = "kShoppingViewCellIdentifier"
    tableView.registerNib(UINib(nibName: "ShoppingViewCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: kShoppingViewCellIdentifier)
    let cell = tableView.dequeueReusableCellWithIdentifier(kShoppingViewCellIdentifier, forIndexPath: indexPath) as! ShoppingViewCell
    return cell
}

并在下面的 cellForRowAtIndexPath

中使用它
let cell = ShoppingViewCell.cellForTableView(tableView, atIndexPath: indexPath)
// do something with your cell

希望对您有所帮助。

更新 Swift 3 和 Swift 4

class func cellForTableView(tableView: UITableView, atIndexPath indexPath: IndexPath) -> YourCustomTableViewCell {
    let kYourCustomTableViewCellIdentifier = "kYourCustomTableViewCellIdentifier"
    tableView.register(UINib(nibName: "YourCustomTableViewCell", bundle: Bundle.main), forCellReuseIdentifier: kYourCustomTableViewCellIdentifier)
    let cell = tableView.dequeueReusableCell(withIdentifier: kYourCustomTableViewCellIdentifier, for: indexPath) as! YourCustomTableViewCell
    return cell
}