简体   繁体   中英

How to handle UICollectionView in UITableViewCell with MVVM

I'm working on an app that has the following View Hierarachy:

ViewController -> contains UITableView -> contains CustomTableViewCell -> contains UICollectionView -> contains CustomCollectionViewCell

Now I've created a ViewModel corresponding to the ViewController . The ViewModel contains the model objects for CustomTableViewCells , ie the number of CustomTableViewCells to show and what content to show in each CustomTableViewCell .

class ViewModel
{
    //MARK: Private Properties
    private var libraries = [Library](){
        didSet{
            self.reloadTableViewClosure?()
        }
    }

    //MARK: Internal Properties
    var reloadTableViewClosure: (()->())?
    var numberOfLibraries: Int{
        return self.libraries.count
    }

    //MARK: Internal Methods
    func getLibrary(at indexPath: IndexPath) -> Library
    {
        return self.libraries[indexPath.row]
    }

    //MARK: Initializer
    init()
    {
        self.fetchLibraryList()
    }

    //MARK: Private Methods
    private func fetchLibraryList()
    {
        if let path = Bundle.main.path(forResource: "LibraryList", ofType: "json")
        {
            if let libraryList = try? JSONDecoder().decode([Library].self, from: Data(contentsOf: URL(fileURLWithPath: path)))
            {
                self.libraries = libraryList
            }
        }
    }
}

I want to know how should I handle UICollectionView with MVVM?

  1. Should I make the main ViewController the delegate & dataSource for both UITableView & UICollectionViews ?

  2. Where should I keep the model objects for CustomCollectionViewCells ? In the same ViewModel or should I make a different one?

What i can figure out in this situation is as below,

You should create 3 ViewModels

  1. ViewModel for ViewController
  2. CustomTableViewCellViewModel for CustomTableViewCellView
  3. CustomCollectionViewCellViewModel for CustomCollectionViewCellView

And here is how your ViewModels should look like,

class ViewModel
{
    private var cellVMs = [CustomTableViewCellViewModel] = []

    var reloadTableViewClosure: (()->())?

    var numberOfLibraries: Int {
        return self.cellVMs.count
    }

    func getLibraryCellVM(at indexPath: IndexPath) -> CustomTableViewCellViewModel
    {
        return self.cellVMs[indexPath.row]
    }

    //MARK: Initializer
    init()
    {
        self.fetchLibraryList()
    }

    //MARK: Private Methods
    private func fetchLibraryList()
    {
        if let path = Bundle.main.path(forResource: "LibraryList", ofType: "json")
        {
            if let libraryList = try? JSONDecoder().decode([Library].self, from: Data(contentsOf: URL(fileURLWithPath: path)))
            {
                libraryList.forEach({
                    cellVMs.append(CustomTableViewCellViewModel(library: $0))
                })
                self.reloadTableViewClosure?()
            }
        }
    }
}

Your CustomTableViewCellViewModel will look like this,

class CustomTableViewCellViewModel {

        var booksVMs: [CustomCollectionViewCellViewModel] = []

        var library: Library!

        init(library: Library) {
            self.library = library

            // Initialize booksVMs
            library.books.forEach({
                booksVMs.append(CustomCollectionViewCellViewModel.init(book: $0))
            })
        }

        var numberOfBooks: Int {
            self.booksVMs.count
        }

        func bookViewModel(at indexPath: IndexPath) -> CustomCollectionViewCellViewModel {
            return self.booksVMs[indexPath.row]
        }
    }

and finally CustomCollectionViewCellViewModel will look like this,

class CustomCollectionViewCellViewModel {

   var book: Book!

   init(book: Book) {
     self.book = book
   }

   var bookName: String? {
      return self.book.name
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM