我正在设置TableView,想知道用viewModel设置UITableViewCells的正确方法是什么。
我们说我有一个模特:
class Item {
var date: Date!
var info: String?
}
我的主ViewController的viewModel有一个属性,它是一个Item对象数组。
var date: String
和var info: String
等属性(使用Item初始化程序,基本上格式化的数据将显示在单元格内)还是我应该将Item对象保留在这里?我的主viewController(与tableView相关的方法)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as? ItemTableViewCell
cell?.viewModel = viewModelForCell(at: indexPath.row)
cell?.setupCell()
return cell ?? UITableViewCell()
}
private func viewModelForCell(at index: Int) -> ItemTableViewCellRepresentable {
let item = viewModel?.items[index]
if let item = item {
return ItemTableViewModel(item: item, formatter: viewModel.cellDateFormatter)
}
return ItemTableViewModel()
}
cell的viewModel协议:
protocol ItemTableViewCellRepresentable {
var date: String { get }
var info: String? { get }
init(item: Item, formatter: DateFormatter)
}
cell的viewModel类:
class ItemTableViewModel: ItemTableViewCellRepresentable {
var date: String
var info: String?
required init(item: Item, formatter: DateFormatter) {
self.date = formatter.string(from: item.date)
self.info = item.info
}
init() {
self.date = ""
self.info = ""
}
}
和我的手机:
(...)
var viewModel: ItemTableViewCellRepresentable?
func setupCell() {
guard let viewModel = viewModel else {
return
}
dateLabel.text = viewModel.date
descriptionLabel.text = viewModel.info ?? "no info"
}
答案 0 :(得分:1)
你的ViewModel协议应该有Representable
信息,这些信息将显示为查看MVVM的这个概念,ViewModel只是给他的视图信息只显示
所以安排你所有的MVVM:
<强>模型强>:
刚刚用于将json映射到数据模型
class Item {
var date: Date!
var info: String?
}
CellRepresentable :
查看所需内容,单元格需要date
和information
为String
protocol ItemTableViewCellRepresentable {
var date: String { get }
var info: String? { get }
init(item: Item)
}
ViewModel :
所有逻辑,API调用(DateFormatting,等等)
ItemTableViewModel
必须引用Model。在MVVM中ViewModel在Model
class ItemTableViewModel: ItemTableViewCellRepresentable {
var item:Item
var date: String {
return item.date.getItemFullDate()
}
var info: String? {
return item.info
}
required init(item: Item) {
self.item = item
}
}
同样在您的MainViewController
相反,您必须将项目转换为Maincontroller private func viewModelForCell(at index: Int) ->
只需转到MainViewModel
即可将其转换为CellRepresentable
所以在你的MainViewController
ViewModel应该是那样的
calss MainViewModel{
var dataSource:[CellRepresentable] = [CellRepresentable]()
func getDataFromAPI( _ completion:(()->() ){
// Update Data Source
// there use map to convert Items to CellRepresentable and append to
datasourec array
}
}
对于DatFormatter
,最好将General extension
用于Handel这个给你
protocol Dateable {
func getItemFullDate() -> String
func getItemHours() -> String
}
extension Date: Dateable {
var formatter: DateFormatter { return DateFormatter() }
/** Return a Item FullDate */
func getItemFullDate() -> String {
// Customize a date formatter
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
formatter.timeZone = TimeZone(abbreviation: "UTC")
return formatter.string(from: self)
}
/** Return a item shor Time hour */
func getItemHours() -> String {
// Customize a date formatter
formatter.dateFormat = "HH:mm"
formatter.timeZone = TimeZone(abbreviation: "UTC")
return formatter.string(from: self)
}
// You can add many cases you need like string to date formatter
}