1

I want the property "cellViewModel" as generic so I can reuse BaseCustomCell with a different types of models. Ex.

 struct CELLVIEWMODEL {
   var name: String
   var address: String
 }
 class BaseCustomCell: UITableViewCell {
       var cellViewModel: CELLVIEWMODEL  //should support different model types CELLVIEWMODEL1,CELLVIEWMODEL2
       {
        didSet() {
          setValuesInSubClasses
        }
      }
      func setValuesInSubClasses() {
       //subclass will implement
      }
 }

 class subCell: BaseCustomCell {
     override func setValuesInSubClasses() {
       //set value from cellViewModel
      }
 }

//This is how i am setting from cellForRowAtIndexPath method:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: viewModel.getCellId(), for: indexPath) as! BaseCustomCell
        cell.cellViewModel = viewModel.getCellModelAtIndexPath(indexPath) //this will set values for subclasses
        return cell
    }

Now, I am creating new BaseCustomCell each time for different types of cellViewModel. Could you help with any solution?

Avijit Nagare
  • 8,482
  • 7
  • 39
  • 68

1 Answers1

1

There are several ways to achieve your goals.

You can make the actual BaseCustomCell glass generic, but be aware if you use Storyboards, this isn't a solution, since you'd need to hardcode the generic type into the storyboard.

The other solution that works with storyboards too is to declare your viewmodel as a protocol, then you can replace it with any concrete implementation of the protocol.

protocol CellViewModel {
    var name: String { get }
    var address: String { get }
}

class BaseCustomCell: UITableViewCell {
    var cellViewModel: CellViewModel {
        didSet() {
            setValuesInSubClasses
        }
    }
    
    func setValuesInSubClasses() {
       //subclass will implement
    }
}

class SubCell: BaseCustomCell {
     override func setValuesInSubClasses() {
       //set value from cellViewModel
      }
 }

And then your viewModel.getCellModelAtIndexPath should have a return type of CellViewModel, so it can return any type that conforms to the protocol.

So you simply need to declare your concrete cell view models like class FirstCellViewModel: CellViewModel { ... }, etc. and you can return them from getCellModelAtIndexPath

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • I am not using storyboard. It looks good to me can you add some more explanation please. – Avijit Nagare Sep 22 '20 at 09:13
  • @AvijitNagare not sure what more can I explain without going into a more specific problem. As I've said, just declare the type of `cellViewModel` as the protocol, make your `viewModel.getCellModelAtIndexPath` have the return type of the protocol, then inside the implementation of `getCellModelAtIndexPath`, you can return the concrete view model types depending on whatever criteria you have. – Dávid Pásztor Sep 22 '20 at 09:17
  • Was not able to set values for CellViewModel protocol type in subclass as i declared CellViewModel(Base Protocol) with not properties. but i subclass has properties and need to update cellViewModel(Whose properties not matching in base cellViewModel). any solution to this. – Avijit Nagare Oct 09 '20 at 04:10
  • @AvijitNagare just cast the `cellViewModel` to the concrete type using `cellViewModel as? YourType` – Dávid Pásztor Oct 09 '20 at 08:30