寻找更通用的方法来使UITableViewCells出队

时间:2019-05-01 06:46:51

标签: swift xcode

研究此主题后,我发现以下代码:

protocol ReusableView {

      static var reuseIdentifier: String { get }
}

extension ReusableView {

       static var reuseIdentifier: String {
           return String(describing: self)
    }
}
extension UITableViewCell: ReusableView {}

extension UITableView {

func dequeueReusableCell<T: UITableViewCell>(for indexPath: IndexPath) -> T {
    guard let cell = dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as? T else {
        fatalError("Unable to Dequeue Reusable Table View Cell")
    }

    return cell
  }
}

Like here suggested

我的问题是,尽管情节提要中定义的所有原型单元都有唯一的ReuseIdentifiers,但T.reuseIdentifier始终相同:UITableViewCell。

即使我定义了以下代码

class c1 : UITableViewCell {}
class c2 : UITableViewCell {}
class c3 : UITableViewCell {}

并将c1,c2,c3分配给三个原型单元,返回值仍为UITableViewCell。 因此,所示示例似乎是推广主题的一种好方法,但缺少某些内容。

我的代码要求调用出队方法:

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(for: indexPath)

    // Configure the cell...
    let place = places[indexPath.row]
    cell.textLabel?.text = place.name
    cell.detailTextLabel?.text = "\(place.timestamp)"
    return cell
}

1 个答案:

答案 0 :(得分:2)

调用该方法时,您需要指定所需的表视图单元格类型:

let cell: c1 = dequeueReusableCell(for: indexPath)

链接的教程的后面部分也提到了这一点:

  

请记住,我们利用泛型和类型推断。我们想   使WeatherDayTableViewCell实例而不是UITableViewCell出队   实例。但是编译器应该如何知道我们要出队   WeatherDayTableViewCell个实例?编译器尝试推断   我们在tableView(_:cellForRowAt:)中定义的单元格常量的类型。   从return cell tableView(_:cellForRowAt:)看来,   通过检查方法定义,它推断出单元格应该是   输入UITableViewCell。编译器是正确的。解决方案非常   简单。声明单元格常量时,我​​们需要显式   指定其类型。然后,编译器了解到   dequeueReusableCell(for:)方法应返回一个   WeatherDayTableViewCell实例。

此外,我认为使用String(describing: self)是获取类名的一种不好的方法。如果self实现CustomStringConvertible并具有自定义description属性,这可能会破坏您的代码。更好的方法是使用:

return String(describing: Self.self)