如何在协议中正确使用associatedType

时间:2018-10-09 21:52:18

标签: ios swift mvvm swift-protocols associated-types

我正试图为我的tableviewcell提供一个面向协议的MVVM。我有很多。

我的viewModel

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

我的view

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

我的class符合性

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

当前设置导致以下错误:

  

类型'PlainTableViewCell'不符合协议   'PlainTableViewCellType'

如果可以,我可以使它工作:

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

但是我想拥有一个associatedType,所以我可以在所有PlainTableViewCellType函数中强制执行相同的模型

编辑: 我很高兴听听替代方案,但首先我想知道为什么这行不通。

2 个答案:

答案 0 :(得分:1)

您必须创建PlainTableViewCellModelType实现,并在单元格实现中声明typealias。将其用作setupUI(forViewModel:)中参数的类型,因为编译器无法推断关联的类型。

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

答案 1 :(得分:0)

在协议中,您需要删除 PlainTableViewCellModelType

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

,在PlainTableViewCell中,您需要添加以下内容:

typealias viewModel = PlainTableViewCellModelType