有一些困难让我的通用视图生成器工作。
背后的想法是拥有一系列不同的具体视图设置。 生成结果视图我已在下面的pastebin中创建了该函数。
但它无法推断出细胞的正确类型。 任何人都能给我一个暗示吗?
//: Playground - noun: a place where people can play
import UIKit
import PlaygroundSupport
// 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
}
// Concrete Cells
final class Concrete1Cell: UIView, CellType {
func configure(with setting: SettingType) {
print("Configured Cell 1")
self.backgroundColor = setting.color
}
}
final class Concrete2Cell: UIView, CellType {
func configure(with setting: SettingType) {
print("Configured Cell 2")
self.backgroundColor = setting.color
}
}
// Generic generator
func makeConcreteCell<S: SettingType, T: CellType>(_ setting: S) -> T {
switch setting {
case is Concrete1Setting:
return Concrete1Cell() as! T
case is Concrete2Setting:
return Concrete2Cell() as! T
default: fatalError()
}
}
// Test
var cells: [CellType] = [Concrete1Cell(), Concrete2Cell()]
let settings: [SettingType] = [Concrete1Setting(), Concrete2Setting()]
for setting in settings {
cells.append(makeConcreteCell(setting)) // CompileError: Generic parameter 'S' could not be inferred
}
// expect array equal to [Concrete1Cell, Concrete2Cell]
答案 0 :(得分:0)
您不需要makeConcreteCell
的通用功能。只需要它并返回原型:
func makeConcreteCell(_ setting: SettingType) -> CellType {
switch setting {
case is Concrete1Setting:
return Concrete1Cell()
case is Concrete2Setting:
return Concrete2Cell()
default: fatalError()
}
}
当您希望编译器为每种特定类型编写特定函数时,将使用泛型。这不是你需要的。一个功能有效。
您想将CellType
用作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))
}