想象一下你的数据会是这样的:
class TableViewModel {
let items: [Any] = [
User(name: "John Smith", imageName: "user3"),
"Hi, this is a message text. Tra la la. Tra la la.",
Bundle.main.url(forResource: "beach@2x", withExtension: "jpg")!,
User(name: "Jessica Wood", imageName: "user2"),
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
]
}
所以通常我们会在tableView(_:cellForRowAt:) 方法中实现它,其中包含许多if let ...
防止这种情况的一种方法是使用泛型类型。泛型编程是避免样板代码的绝佳方式,有助于在编译期间定义错误。
通用代码使您能够编写灵活、可重用的函数和
可以与任何类型一起使用的类型,具体取决于您的要求
定义。您可以编写避免重复并表达其
以清晰、抽象的方式表达意图。
Apple Documentation
让我们制定每个单元应遵循的第一个协议。
protocol ConfigurableCell {
associatedtype DataType
func configure(data: DataType)
}
//example of UserCell
class UserCell: UITableViewCell, ConfigurableCell {
@IBOutlet weak var avatarView: UIImageView!
@IBOutlet weak var userNameLabel: UILabel!
func configure(data user: User) {
avatarView.image = UIImage(named: user.imageName)
userNameLabel.text = user.name
}
}
现在我们可以创建一个通用的单元格配置器来配置我们的表格单元格。
protocol CellConfigurator {
static var reuseId: String { get }
func configure(cell: UIView)
}
class TableCellConfigurator<CellType: ConfigurableCell, DataType>: CellConfigurator where CellType.DataType == DataType, CellType: UITableViewCell {
static var reuseId: String { return String(describing: CellType.self) }
let item: DataType
init(item: DataType) {
self.item = item
}
func configure(cell: UIView) {
(cell as! CellType).configure(data: item)
}
}
现在我们需要对 ViewModel 进行一些调整:
typealias UserCellConfigurator = TableCellConfigurator<UserCell, User>
typealias MessageCellConfigurator = TableCellConfigurator<MessageCell, String>
typealias ImageCellConfigurator = TableCellConfigurator<ImageCell, URL>
class TableViewModel {
let items: [CellConfigurator] = [
UserCellConfigurator(item: User(name: "John Smith", imageName: "user3")),
MessageCellConfigurator(item: "Hi, this is a message text. Tra la la. Tra la la."),
ImageCellConfigurator(item: Bundle.main.url(forResource: "beach@2x", withExtension: "jpg")!),
UserCellConfigurator(item: User(name: "Jessica Wood", imageName: "user2")),
MessageCellConfigurator(item: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."),
]
}
就是这样!
您无需编辑 ViewController 的代码即可轻松添加新单元格。
让我们在表格视图中添加一个WarningCell。
1.符合ConfigurableCell协议。
2.在 ViewModel 的类中为该单元格添加 TableCellConfigurator。
class WarningCell: UITableViewCell, ConfigurableCell {
@IBOutlet weak var messageLabel: UILabel!
func configure(data message: String) {
messageLabel.text = message
}
}
//cell configurator for WarningCell
TableCellConfigurator<WarningCell, String>(item: "This is a serious warning!")
更多信息请关注link