Создание единого .xib для разных классов UITableViewCell
Я столкнулся с проблемой
У меня есть файл 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
![введите описание изображения здесь]()
с class name
как: NNVerticalStackTableViewCell
и cell identifier
как: NNVerticalStackTableViewCell
Теперь я создал подкласс NNVerticalStackTableViewCell
как:
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
с интерфейсом NNVerticalStackTableViewCell.xib
.
Подобно классу NNPropertiesUnderProjectTableViewCell
у меня есть много других классов, которые используют тот же интерфейс, что и 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
и не хочу повторять код.
Ответы
Ответ 1
Вы можете, но вместо использования UITableViewCell
используйте аналогичный UIView
Создайте xib для представления содержимого ячейки, дайте ему класс (например, CellView
).
В каждом классе ячейки получите CellView
с помощью loadNibNamed
и установите его как представление содержимого ячейки, затем вы можете свободно изменять свойство CellView
и использовать его в качестве представления содержимого класса ячейки
Может быть, есть лучшее решение, но так я делаю это для аналогичного вида UIViewController
, вы также можете попробовать сотовый xib без набора классов в раскадровке и попытаться загрузить его и посмотреть, сохраняется ли ошибка или нет.
Ответ 2
Вы не можете сделать это, так как registerNib:
ожидает тот же экземпляр точного зарегистрированного вида.
Здесь вы можете выполнить репликацию NNVerticalStackTableViewCell.xib
и сохранить NNVerticalStackTableViewCell.swift
в качестве базового класса.
затем создайте что-то вроде NNPropertiesUnderProjectTableViewCell.xib
, где он содержит то же представление, что и до NNVerticalStackTableViewCell.xib
, с добавленными элементами управления. Затем подклассируем его до NNPropertiesUnderProjectTableViewCell.swift
с уникальным идентификатором: NNPropertiesUnderProjectTableViewCell
.
в котором NNPropertiesUnderProjectTableViewCell
является подклассом NNVerticalStackTableViewCell
.
Теперь просто добавьте дополнительные элементы управления, уникальные для класса NNPropertiesUnderProjectTableViewCell
.
Ответ 3
В принципе, вы не можете делать то, что вы пытаетесь сделать, потому что имя класса находится в XIB, поэтому вы всегда получаете экземпляр базового класса, а не какой-либо из ваших подклассов.
Предложение от @Tj3n является хорошим, извлечь общую часть в многоразовое представление и в вашей инициализации суперкласса создать экземпляр этого представления и добавить его. Теперь, когда вы создаете экземпляр подкласса и называет super, общий элемент будет инициализироваться и использоваться подклассом.
Другими словами, используйте композицию для достижения своей цели, а не наследования.
Ответ 4
Вы можете сделать это, если хотите использовать tableViewCell.xib за несколько раз.
Сначала перейдите в файл и создайте новый файл (Cocoa Touch Class).
![Класс CocoaTouch]()
Создать файл TableViewCell с .xib
![TableViewCell]()
Теперь просто создайте свой собственный дизайн ячеек
![Дизайн]()
Теперь добавьте этот код в свой файл TableViewCell.swift
![Изображение]()
Теперь просто добавьте идентификатор в свой TableView Cell, как это (где вы хотите добавить этот пользовательский TableviewCell)
![cell]()
Теперь просто возьмите его как свою ячейку. Вот как...
![Таблица]()
И Бинго Вы получили это.
Теперь просто добавьте ячейку как! TableViewCell в любом файле TableViewController (у вас одинаковые результаты с тем же дизайном).
![OutPut1]()
Здесь нажмите "Сначала" (Load First TableViewController)
![FirstTable]()
Вкл. второй щелчок (Load Second TableViewController)
![SecondTable View]()
Ответ 5
NNPropertiesUnderProjectTableViewCell не регистрируется для Cellidentifier.