为不同的 UITableViewCell 创建单个 .xib 类

Creating single .xib for different UITableViewCell classes

我遇到了问题

我有一个 NNVerticalStackTableViewCell.xib 文件及其对应的 NNVerticalStackTableViewCell.swift 文件。

NNVerticalStackTableViewCell.swift 文件的代码

class NNVerticalStackTableViewCell: UITableViewCell
{
    //MARK: Outlets
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var verticalStack: NNVerticalStackView!

    //MARK: Internal Properties
    var titleString : String?
        {
        set{
            self.titleLabel.text = newValue
        }
        get{
            return self.titleLabel.text
        }
    }

    //MARK: View Lifecycle Methods
    override func awakeFromNib()
    {
        super.awakeFromNib()
        self.titleLabel.text = nil
    }

    //MARK: Internal Methods
    func addViewsInVerticalStack(viewsArray : [UIView])
    {
        for view in viewsArray
        {
            self.verticalStack.insertStackItem(view)
        }
    }
}

NNVerticalStackTableViewCell.xib 文件的接口

with class name as : NNVerticalStackTableViewCell and cell identifier as : NNVerticalStackTableViewCell

现在我创建了 NNVerticalStackTableViewCell 的子class 作为:

class NNPropertiesUnderProjectTableViewCell: NNVerticalStackTableViewCell
{
    //MARK: Internal Properties
    var completionHandler : ((NNSearchPreference) -> Void)?

    //MARK: Internal Methods
    func configureCell(_ propertiesUnderProjectArray : [[String : Any]])
    {
        var viewsArray = [UIView]()
        for dict in propertiesUnderProjectArray
        {
            let elementView = NNPropertiesUnderProjectElementView.loadFromNib()
            elementView?.configureViewWith(buttonTitleString: dict["displayString"] as! String, searchPreference: dict["searchPreference"] as! NNSearchPreference, completionHandler: {[weak self] (searchPreference) in
                if let handler = self?.completionHandler
                {
                    handler(searchPreference)
                }
                })
            viewsArray.addObject(elementView)
        }
        self.addViewsInVerticalStack(viewsArray: viewsArray)
    }
}

现在我要做的是使用 NNPropertiesUnderProjectTableViewCell class 和 NNVerticalStackTableViewCell.xib 接口。

类似于NNPropertiesUnderProjectTableViewCell class 我有许多其他class使用与NNVerticalStackTableViewCell.xib相同的界面并相应地自定义它。

在我的 ViewController 中,我注册了 NNVerticalStackTableViewCell.xib 然后将单元格创建为:

self.tableView.register(UINib(nibName: "NNVerticalStackTableViewCell"), forCellReuseIdentifier: "NNVerticalStackTableViewCell")


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
            let propertiesUnderProjectCell = tableView.dequeueReusableCell(withIdentifier: "NNVerticalStackTableViewCell", for: indexPath as IndexPath) as! NNPropertiesUnderProjectTableViewCell
    }

但是,我遇到了异常:

Could not cast value of type 'NNVerticalStackTableViewCell' (0x100945878) to 'NNPropertiesUnderProjectTableViewCell' (0x100949330).

任何人都可以建议如何解决这个问题。我想使用单个 .xib 并且不想重复代码。

可以,但是不要使用 UITableViewCell,而是使用类似的 UIView

为单元格内容视图创建一个 xib,给它一个 class(比如 CellView)。 在每个单元格class中,获取CellViewloadNibNamed并将其设置为单元格内容视图,然后可以自由更改CellView的属性和将其用作其他单元格 class 的内容视图

也许有更好的解决方案,但对于类似的外观 UIViewController,我就是这样做的,您也可以尝试在情节提要中未设置 class 的单元格 xib 并尝试加载它,看看是否错误是否仍然存在

基本上,你不能完全按照你想做的去做,因为 class 名称在 XIB 中,所以你总是得到基 class 的实例,而不是任何你的子classes.

@Tj3n 的建议很好,将公共部分提取到可重用视图中,然后在您的 superclass 初始化中创建该视图的实例并添加它。现在,当您实例化一个 subclass 并调用 super 时,公共元素将被初始化并由 subclass.

使用

换句话说,使用组合来实现你的目标,而不是继承。

NNPropertiesUnderProjectTableViewCell 没有注册 Cellidentifier。

如果你想在多个时间使用tableViewCell.xib,你可以这样做。 首先转到文件并创建新文件(Cocoa 触摸 Class)。

使用 .xib 创建 TableViewCell 文件

现在简单地创建您的自定义单元格设计

现在将此代码添加到您的文件中 TableViewCell.swift

现在只需像这样在您的 tableView 单元格中添加标识符(您要在其中添加此自定义 TableviewCell)

现在就把它当成你的Cell吧..

还有宾果你猜对了..

现在只需将单元格添加为!任何 TableViewController 文件中的 TableViewCell(您使用相同的设计得到相同的结果。)

点击这里(首先加载TableViewController)

第二次点击(加载第二个 TableViewController)

你不能那样做,因为 registerNib: 期望确切注册视图的相同实例。

从这里你可以做的是复制 NNVerticalStackTableViewCell.xib 并保留 NNVerticalStackTableViewCell.swift 作为你的基础 class。

然后创建类似 NNPropertiesUnderProjectTableViewCell.xib 的内容,其中包含与之前添加的控件完全相同的视图 NNVerticalStackTableViewCell.xib。然后使用唯一标识符将其子class 到NNPropertiesUnderProjectTableViewCell.swiftNNPropertiesUnderProjectTableViewCell.

其中 NNPropertiesUnderProjectTableViewCellNNVerticalStackTableViewCell 的子类。

从这里,只需添加 NNPropertiesUnderProjectTableViewCell class.

独有的额外控件