简体   繁体   中英

Swift 5: How to add dependency injection to a programmatic UITableviewCell

I would like to add my viewmodel to my CustomTableViewCell, and then be able to bind the data that I have in my viewmodel with my func configure(), but when I try I get an error in the override init "Property 'self.viewModel' not initialized at super.init call". I tried to create another init but I get another error "Must call a designated initializer of the superclass 'UITableViewCell'"

This is my code:

final class CustomTableViewCell: UITableViewCell {
    
    // MARK: - Properties

    private let returnAmount = UILabel.subtitle()
    private let margin: CGFloat = 15
    static let identifier = "CustomTableViewCell"
    static let rowHeigh: CGFloat = 175
    
    var viewModel: TableViewCellViewModel
    
    // MARK: - Init
    
    init(viewModel: DetailViewModel) {
        self.viewModel = viewModel
    }
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        contentView.backgroundColor = UIColor.clear
        backgroundColor = UIColor.clear

        setupViews()
    }
    
    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - Configure View
    func configure(){
        returnAmount.text = viewModel.returnAmount
    }

View Model:

import Foundation

class TableViewCellViewModel {

    private let data: Contacts?
    
    init(data: Contacts) {
        self.data = data
    }
    
    var returnAmount: String {
        let amount = data?.returnAmount ?? 0
        return amount.formatThousandsAndDecimal(intValue: amount)
    }

How can I solve it in these cases?

The ViewModel is not initialized when the cell does and you assign it later on. You must tell the run time

  • This property will have a value when needed (!)

Or

  • The property is init with nil and might have a value later (?)

So Use either

var viewModel: TableViewCellViewModel!

Or

var viewModel: TableViewCellViewModel?

And then set the VM in the configure function

func configure(_ vm: TableViewCellViewModel) {}

Generally speaking injecting properties into Cells on init is not easy as you are not controlling the Cell Lifecycle

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