Как я могу исправить эту конфликтующую ошибку соответствия? - PullRequest
0 голосов
/ 18 марта 2020

Я пытаюсь создать ProfileCellController, который можно использовать для настройки ячейки в моем UITableView.

Поскольку моя таблица может иметь несколько типов ячеек, я надеялся использовать обобщенные значения для установки введите необходимую ячейку и используйте метод configure для установки реквизита.

Это то, что у меня есть:

import UIKit

public protocol ProfileLoadedView {
  func display(_ viewModel: ProfileViewModel)
}

public class SingleLineCell: UITableViewCell { }
public class MultiLineWithIconCell: UITableViewCell { }

public final class ProfileCellController<T> where T: UITableViewCell {

  private var cell: T?

  func view(in tableView: UITableView) -> UITableViewCell {
    cell = tableView.dequeueReusableCell()
    return cell!
  }
}

extension ProfileCellController: ProfileLoadedView where T: SingleLineCell {
  public func display(_ viewModel: ProfileViewModel) {

  }
}

extension ProfileCellController: ProfileLoadedView where T: MultiLineWithIconCell {
  public func display(_ viewModel: ProfileViewModel) {

  }
}

extension UITableView {
  func dequeueReusableCell<T: UITableViewCell>() -> T {
    let identifier = String(describing: T.self)
    return dequeueReusableCell(withIdentifier: identifier) as! T
  }
}

Однако второе расширение имеет ошибку

Конфликт соответствия ProfileCellController с протоколом ProfileLoadedView; не может быть более одного соответствия, даже с разными условными границами

Возможно ли достичь этого?

Ответы [ 2 ]

2 голосов
/ 18 марта 2020

К сожалению, это еще не поддерживается. Вы не можете иметь несколько условных соответствий одному и тому же протоколу с разными условиями.

Однако вы можете безоговорочно заставить ProfileCellController соответствовать протоколу ProfileLoadedView, обеспечить реализацию по умолчанию для метода display и затем предоставить более конкретные c реализации для подклассов.

extension ProfileCellController: ProfileLoadedView {
  public func display(_ viewModel: ProfileViewModel) {
    print("default")
  }
}

extension ProfileCellController where T: SingleLineCell {
    public func display(_ viewModel: ProfileViewModel) {
        print("singleline")
    }
}

extension ProfileCellController where T: MultiLineWithIconCell {
  public func display(_ viewModel: ProfileViewModel) {
    print("multiline")
  }
}

ProfileCellController<SingleLineCell>().display(ProfileViewModel()) // prints singleline
ProfileCellController<MultiLineWithIconCell>().display(ProfileViewModel()) // prints multiline
1 голос
/ 18 марта 2020

Почему бы вам не создать класс и не использовать наследование, чтобы ваш протокол мог быть реализован только один раз?

public class GenericCell: UITableViewCell { }
public class SingleLineCell: GenericCell { }
public class MultiLineWithIconCell: GenericCell { }

    extension ProfileCellController: ProfileLoadedView where T: GenericCell {
  public func display(_ viewModel: ProfileViewModel) {

    switch cell {
     case is SingleLineCell:
      // impl goes here
      return
     case is MultiLineWithIconCell:
     // impl goes here
     return
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...