How can I correctly use associatedType in my protocol

徘徊边缘 提交于 2020-01-16 02:50:50

问题


I’m trying to come up with an protocol-oriented MVVM for my tableviewcells. I have lots of them.

my viewModel

protocol PlainTableViewCellModelType {
    var backgroundColor : UIColor {get}
    var textColor: UIColor {get}
    var titleFont : UIFont {get }
    var accessoryType : UITableViewCellAccessoryType {get}
    var textLabelNumberOfLines: Int {get}
}

my view

protocol PlainTableViewCellType{
    associatedtype viewModel : PlainTableViewCellModelType
    func setupUI(forViewModel viewModel: viewModel)
}

my class conformance

class PlainTableViewCell : CCTableViewCell, PlainTableViewCellType{

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }

    func setupUI(forViewModel viewModel: PlainTableViewCellModelType){
        contentView.backgroundColor = viewModel.backgroundColor
        textLabel?.textColor = viewModel.textColor
        textLabel?.font = viewModel.titleFont
        accessoryType = viewModel.accessoryType
        textLabel?.numberOfLines = viewModel.textLabelNumberOfLines
    }
}

The current setups results in the following error:

Type 'PlainTableViewCell' does not conform to protocol 'PlainTableViewCellType'

I can get it to work if I do:

protocol PlainTableViewCellType{
    func setupUI(forViewModel viewModel: PlainTableViewCellModelType)
}

But I want to have an associatedType so I can enforce same model in all my PlainTableViewCellType functions

EDIT: I'm happy to listen to alternatives, but first I want to know why this doesn't work.


回答1:


You must create PlainTableViewCellModelType implementation and declare typealias in cell implementation. Use it as type for parameter in setupUI(forViewModel:) because compiler cant infer associated type.

protocol PlainTableViewCellModelType {
    var backgroundColor : UIColor { get }
    var textColor: UIColor { get }
    var titleFont : UIFont { get }
    var accessoryType : Int { get}
    var textLabelNumberOfLines: Int { get }
}

protocol PlainTableViewCellType{
    associatedtype viewModel : PlainTableViewCellModelType
    func setupUI(forViewModel viewModel: viewModel)
}

struct PlainTableViewCellModel: PlainTableViewCellModelType {
    var backgroundColor : UIColor
    var textColor: UIColor
    var titleFont : UIFont
    var accessoryType : Int
    var textLabelNumberOfLines: Int
}


class PlainTableViewCell : UITableViewCell, PlainTableViewCellType {
    typealias viewModel = PlainTableViewCellModel

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }

    func setupUI(forViewModel viewModel: PlainTableViewCellModel) {
        contentView.backgroundColor = viewModel.backgroundColor
        textLabel?.textColor = viewModel.textColor
        textLabel?.font = viewModel.titleFont
        textLabel?.numberOfLines = viewModel.textLabelNumberOfLines
    }
}



回答2:


In protocol you need remove PlainTableViewCellModelType:

protocol PlainTableViewCellType{
    associatedtype viewModel
    func setupUI(forViewModel viewModel: viewModel)
}

and in PlainTableViewCell you need add something like this:

typealias viewModel = PlainTableViewCellModelType


来源:https://stackoverflow.com/questions/52729852/how-can-i-correctly-use-associatedtype-in-my-protocol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!