hoa*_*Cap 0 generics uitableview swift
我正在开发一个表格视图(类似于 Facebook Messenger 的表格视图),其中有不同的单元格类型(图像、文本、视频等)。我想要存档的是,我想声明一个列表message model,我将配置tableView,以便单元格将由模型本身确定和配置。为了做到这一点,我需要以某种方式告诉它关联的是model哪个UITableViewCell类。基本上我想要一个像这样的协议:
protocol ChatMessageDisplayable {
static var myCellType: UITableViewCell { get } //Defines the UITableViewCell class this model is associated with
func configure(cell: /*the associated cell type*/) // Let the model itself configure the cell.
}
Run Code Online (Sandbox Code Playgroud)
然后我在我的 ViewController 中声明一个数组
messageModels = [ChatMessageDisplayable]
我的 UITableViewDataSource 实现:
public func numberOfSections(in tableView: UITableView) -> Int {
return messageModels.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = messageModel[indexPath.row]
let cellIdentifier = /* Name of the UITableViewCell this model is associated with */
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
model.configure(cell: cell)
return cell
}
Run Code Online (Sandbox Code Playgroud)
无论如何我可以实现这个目标吗?
想象一下你的数据会是这样的:
\n\nclass TableViewModel {\n let items: [Any] = [\n User(name: "John Smith", imageName: "user3"),\n "Hi, this is a message text. Tra la la. Tra la la.",\n Bundle.main.url(forResource: "beach@2x", withExtension: "jpg")!,\n User(name: "Jessica Wood", imageName: "user2"),\n "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."\n ]\n}\nRun Code Online (Sandbox Code Playgroud)\n\n所以通常我们会在tableView(_:cellForRowAt:)有很多的方法中实现它if let ...
防止这种情况的一种方法是使用泛型类型。通用编程是避免样板代码的绝佳方法,并有助于在编译期间定义错误。
\n\n\n\n\n通用代码使您能够编写灵活、可重用的函数和类型,这些函数和类型可以与任何类型一起使用,具体取决于您定义的要求。您可以编写避免重复并以清晰、抽象的方式\n 表达其意图的代码。\n Apple 文档
\n
让\xe2\x80\x99s制定每个单元应遵守的第一个协议。
\n\nprotocol ConfigurableCell {\n associatedtype DataType\n func configure(data: DataType)\n}\n\n//example of UserCell\nclass UserCell: UITableViewCell, ConfigurableCell {\n @IBOutlet weak var avatarView: UIImageView!\n @IBOutlet weak var userNameLabel: UILabel!\n\n func configure(data user: User) {\n avatarView.image = UIImage(named: user.imageName)\n userNameLabel.text = user.name\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n现在我们可以创建一个通用单元格配置器来配置我们的表格单元格。
\n\nprotocol CellConfigurator {\n static var reuseId: String { get }\n func configure(cell: UIView)\n}\n\nclass TableCellConfigurator<CellType: ConfigurableCell, DataType>: CellConfigurator where CellType.DataType == DataType, CellType: UITableViewCell {\n static var reuseId: String { return String(describing: CellType.self) }\n\n let item: DataType\n\n init(item: DataType) {\n self.item = item\n }\n\n func configure(cell: UIView) {\n (cell as! CellType).configure(data: item)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n现在我们需要对 ViewModel 进行一些调整:
\n\ntypealias UserCellConfigurator = TableCellConfigurator<UserCell, User>\ntypealias MessageCellConfigurator = TableCellConfigurator<MessageCell, String>\ntypealias ImageCellConfigurator = TableCellConfigurator<ImageCell, URL>\n\nclass TableViewModel {\n let items: [CellConfigurator] = [\n UserCellConfigurator(item: User(name: "John Smith", imageName: "user3")),\n MessageCellConfigurator(item: "Hi, this is a message text. Tra la la. Tra la la."),\n ImageCellConfigurator(item: Bundle.main.url(forResource: "beach@2x", withExtension: "jpg")!),\n UserCellConfigurator(item: User(name: "Jessica Wood", imageName: "user2")),\n 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."),\n ]\n}\nRun Code Online (Sandbox Code Playgroud)\n\n那\xe2\x80\x99就是它!
\n\n您可以轻松添加新单元格,无需编辑 ViewController\xe2\x80\x99s 代码。
\n\n让\xe2\x80\x99s 添加一个WarningCell 到我们的表视图中。
\n\n1.符合ConfigurableCell协议。\n2.在ViewModel\xe2\x80\x99s类中为该单元添加TableCellConfigurator。
\n\nclass WarningCell: UITableViewCell, ConfigurableCell {\n @IBOutlet weak var messageLabel: UILabel!\n\n func configure(data message: String) {\n messageLabel.text = message\n }\n}\n\n//cell configurator for WarningCell\nTableCellConfigurator<WarningCell, String>(item: "This is a serious warning!")\nRun Code Online (Sandbox Code Playgroud)\n\n欲了解更多信息,请点击此链接
\n| 归档时间: |
|
| 查看次数: |
4023 次 |
| 最近记录: |