【发布时间】:2019-01-22 02:22:07
【问题描述】:
问题
我正在创建一个可重用的自定义 UITableViewCell,然后将其子类化以供重用。如何将这些不同的子类设置为链接到同一个 xib 文件?
背景
让我们调用我的自定义 UITableViewCell PickerTableViewCell。这个单元格包括一个UIPickerView,以及关于选择器视图的外观和行为的所有实现。当我想使用这个单元格时,我唯一需要给它的是选择器视图的数据。所以我继承PickerTableViewCell,然后简单地创建我需要的数据源并将其分配给选择器视图。到目前为止,这一切都运作良好。
这里是PickerTableViewCell的相关部分:
class PickerTableViewCell: UITableViewCell {
var picker: UIPickerView! = UIPickerView()
var pickerDataSource: PickerViewDataSource!
override func awakeFromNib() {
super.awakeFromNib()
self.picker = UIPickerView(frame: CGRect(x: 0, y: 40, width: 0, height: 0))
self.picker.delegate = self
self.assignPickerDataSource()
}
// Must be overriden by child classes
func assignPickerDataSource() {
fatalError("Must Override")
}
这是一个子类的例子:
class LocationPickerTableViewCell: PickerTableViewCell {
override func assignPickerDataSource() {
self.pickerDataSource = LocationPickerDataSource()
self.picker.dataSource = self.pickerDataSource
}
}
问题
由于我在各处使用这些单元格,并使用不同的数据源,我创建了一个 xib 文件,该文件定义了单元格的外观,称为 PickerTableViewCell.xib,并将其分配给类 PickerTableViewCell。在我想使用它的视图控制器中,我将单元格注册到viewDidLoad() 中的表格视图。然后,在func tableView(_:, cellForRowAt) 中,我将我想要的子类出列,如下所示:
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier") as! LocationPickerTableViewCell
return cell
这就是问题发生的地方。创建的单元格是PickerTableViewCell,而不是它的子类LocationPickerTableViewCell。这遇到了我放置在被子类覆盖的父类中的致命错误。
我发现解决此问题的唯一方法是为我要创建的每个子类创建一个单独的 xib 文件,并将其分配给相关的子类。虽然这个解决方案确实有效,但在我的项目中拥有所有这些实际上相同的 xib 文件(除了它们被分配到哪个类)感觉不对。
有没有办法可以克服这个问题,让所有这些单元格链接到同一个 xib 文件?
谢谢! :)
【问题讨论】:
-
别觉得有什么办法,要么按代码布局,要么复制Xib,要么使用扩展
-
为什么要麻烦子类?如果唯一的区别是数据源,请在
cellForRowAt中分配数据源 -
@Paulw11 那是我没有考虑过的东西。它适用于某些子类,例如上面的 LocationPickerTableViewCell,但是其他一些具有额外的功能,子类可以更好地工作
-
@RyanSaffer 在 cell 类中通过 `Bundle.main.loadNibNamed' 方法加载 Xib 视图,通过这个你可以在多个类中添加相同的 Xib 视图。
-
@Rocky 这似乎是一个不错的选择,但我已经尝试过并且遇到了各种问题,例如 '[
setValue:forUndefinedKey:]: 这个类不是键值编码-符合关键 headerLabel。 ...你有机会举个例子吗?
标签: ios swift uitableview