es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Swift 5: Cómo añadir la inyección de dependencias a una UITableViewCell programática en un UITableView.

Me gustaría agregar mi ViewModel a mi CustomTableViewCell y luego poder enlazar los datos que tengo en mi ViewModel con mi función configure(), pero cuando intento hacerlo, obtengo un error en el override init “Propiedad ‘self.viewModel’ no inicializada en la llamada super.init”. Intenté crear otro init pero obtengo otro error “Debe llamar a un inicializador designado de la superclase ‘UITableViewCell'”.

Este es mi código:

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

ViewModel:

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

¿Cómo puedo solucionarlo en estos casos?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error “Propiedad ‘self.viewModel’ no inicializada en la llamada a super.init” ocurre porque la propiedad viewModel en la clase CustomTableViewCell no se inicializa durante la llamada a super.init en el inicializador init(style:reuseIdentifier:). Una forma de resolver este problema es hacer que viewModel sea una propiedad opcional y establecer su valor en init(viewModel:), de la siguiente manera:

    final class CustomTableViewCell: UITableViewCell {
    
        // MARK: - Propiedades
    
        private let returnAmount = UILabel.subtitle()
        private let margin: CGFloat = 15
        static let identifier = "CustomTableViewCell"
        static let rowHeigh: CGFloat = 175
    
        var viewModel: TableViewCellViewModel?
    
        // MARK: - Inicialización
    
        init(viewModel: TableViewCellViewModel) {
            self.viewModel = viewModel
            super.init(style: .default, reuseIdentifier: CustomTableViewCell.identifier)
            contentView.backgroundColor = UIColor.clear
            backgroundColor = UIColor.clear
    
            setupViews()
        }
    
        @available(*, unavailable)
        required init?(coder: NSCoder) {
            fatalError("init(coder:) no ha sido implementado")
        }
    
        // MARK: - Configurar Vista
        func configure(){
            returnAmount.text = viewModel?.returnAmount
        }
    }
    

    Al hacer que viewModel sea opcional y usar el operador de encadenamiento opcional (?.) en la función configure(), evitamos el error de la propiedad no inicializada. Sin embargo, esta puede no ser la mejor solución en todos los casos, ya que es posible que viewModel siempre deba ser distinto de nulo. En ese caso, una mejor solución podría implicar pasar un viewModel no nulo a nuestro inicializador, o usar un valor predeterminado para la propiedad.

    En cuanto al error “Debe llamar a un inicializador designado de la superclase ‘UITableViewCell'”, ocurre porque estamos tratando de crear un inicializador adicional que no llama al inicializador designado de UITableViewCell. Para solucionar este problema, debemos eliminar init(style:reuseIdentifier:) y usar solo init(viewModel:), que llama a super.init(style:reuseIdentifier:) según sea necesario.

Comments are closed.