在ViewModel中格式化UITableViewCell日期

时间:2018-05-12 10:43:28

标签: ios swift uitableview mvvm

我正在设置TableView,想知道用viewModel设置UITableViewCells的正确方法是什么。

我们说我有一个模特:

class Item {
   var date: Date!
   var info: String?
}

我的主ViewController的viewModel有一个属性,它是一个Item对象数组。

  1. 我已经宣布了单元格视图模型的协议。它应该包含var date: Stringvar info: String等属性(使用Item初始化程序,基本上格式化的数据将显示在单元格内)还是我应该将Item对象保留在这里?
  2. 谁负责格式化单元格内的日期?我假设单元的视图模型对此负责,但另一方面,在每个ViewModel中使用dateFormatter实例是否有效?也许最好从另一个类传递dateformatter并只保留一个引用?
  3. 我的主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"
        }
    

1 个答案:

答案 0 :(得分:1)

你的ViewModel协议应该有Representable信息,这些信息将显示为查看MVVM的这个概念,ViewModel只是给他的视图信息只显示

所以安排你所有的MVVM:

<强>模型

刚刚用于将json映射到数据模型

class Item {
    var date: Date!
    var info: String?
}

CellRepresentable

查看所需内容,单元格需要dateinformationString

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) ->

中的cellViewModel

只需转到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

    }