Home > Enterprise >  MVVM proper ViewModel format creation to display data in tableview swift iOS
MVVM proper ViewModel format creation to display data in tableview swift iOS

Time:10-15

I want to create a view model with proper format which can be used to display the data inside tableview.

Expected output:

Expected output screenshot image

I've tried to create a view model as below but I was not able to create it in proper format and it's not working.

struct MyViewModel {
   var headerlist : [String]
   var listItem : [ListData] {
       get {
           return [ListData(title: "Check Detailed Info", type: .INFORMATION),ListData(title: "Check Document", type: .DOCUMENTS), ListData(title: "Check Policy", type: .DOCUMENTS)]
       }
   }
}
struct ListData {
   var title: String
   var type: HeaderType
}
enum HeaderType {
   case INFORMATION
   case DOCUMENTS
}

How to create a view model which can be used in tableview delegate methods like below.

    let viewModel =  MyViewModel()
    func numberOfSections(in tableView: UITableView) -> Int {
        return viewModel.headerlist.count
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let sectionitem = viewModel.headerlist[indexpath.section]
        return sectionItem.listItem.count
    }
    public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        ///Will be creating a headerview and title label outlet in it.
        headerView.titleLabel.text = viewModel?.headerlist[section]
        return headerView
    }

I just found some links looking to get proper understandable answer

UITableView with MVVM using Swift

Populate data onto UITableView with MVVM

MVVM in TableView Cell

CodePudding user response:

You have two sections, so you need two arrays in your model.

I would suggest you use something like this:

struct SectionData {
    let type: HeaderType
    let items: [String]
}

enum HeaderType {
   case information = "INFORMATION"
   case documents = "DOCUMENTS"
}

struct MyViewModel {

    var sectionData : [SectionData] {
        get {
            return [
                SectionData(type: .information, items: ["Check Detailed Info"]), 
                SectionData(type: .documents, items:["Check Document","Check Policy"])
            ]
        }
    }
}

Then you can use it in your table view

let viewModel =  MyViewModel()
    func numberOfSections(in tableView: UITableView) -> Int {
        return viewModel.sectionData.count
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.sectionData[section].count
    }
    public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        ///Will be creating a headerview and title label outlet in it.
        headerView.titleLabel.text = viewModel.sectionData[section].type.rawValue
        return headerView
    }

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: indexPath) -> UITableViewCell? {
        let cell = tableview.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = viewModel.sectionData[indexPath.section].items[indexPath.row]
        return cell
    }

Note that this isn't an MVVM approach, but perhaps you have simplified your code for the purposes of the question. If you are going to use static data it would be more efficient to create the data array in the view model init rather than use a computed property.

  • Related