Вам не нужна универсальная функция для makeConcreteCell
. Просто возьми и верни прототипы:
func makeConcreteCell(_ setting: SettingType) -> CellType {
switch setting {
case is Concrete1Setting:
return Concrete1Cell()
case is Concrete2Setting:
return Concrete2Cell()
default: fatalError()
}
}
Обобщения используются, когда вы хотите, чтобы компилятор написал определенную функцию для каждого конкретного типа. Это не то, что вам нужно здесь. Одна функция работает.
Вы хотите использовать CellType
s как UIView
s.
Создайте базовый класс с именем CellTypeClass
, который является UIView
и принимает протокол CellType
:
// Protocols
protocol SettingType {
var color: UIColor { get }
}
protocol CellType {
func configure(with setting: SettingType)
}
// Concrete Settings
final class Concrete1Setting: SettingType {
var color: UIColor = .blue
}
final class Concrete2Setting: SettingType {
var color: UIColor = .green
}
class CellTypeClass: UIView, CellType {
func configure(with setting: SettingType) {
fatalError("You must override this function")
}
}
// Concrete Cells
final class Concrete1Cell: CellTypeClass {
override func configure(with setting: SettingType) {
print("Configured Cell 1")
self.backgroundColor = setting.color
}
}
final class Concrete2Cell: CellTypeClass {
override func configure(with setting: SettingType) {
print("Configured Cell 2")
self.backgroundColor = setting.color
}
}
// Generic generator
func makeConcreteCell(_ setting: SettingType) -> CellTypeClass {
switch setting {
case is Concrete1Setting:
return Concrete1Cell()
case is Concrete2Setting:
return Concrete2Cell()
default: fatalError()
}
}
// Test
var cells: [CellTypeClass] = [Concrete1Cell(), Concrete2Cell()]
let settings: [SettingType] = [Concrete1Setting(), Concrete2Setting()]
for setting in settings {
cells.append(makeConcreteCell(setting))
}