Подклассы UICollectionviewcell не могут быть реализованы как обобщенные - PullRequest
0 голосов
/ 09 мая 2019

Я хочу динамически создать несколько коллекционных представлений.

При вызове своей фабричной функции я хочу передать ей подклассный тип UICollectionViewCell.Я использую типизированные дженерики, чтобы сделать это.Однако компилятор останавливает меня и заставляет усомниться в моем понимании полиморфизма в Swift.

Может ли кто-нибудь пролить свет на этот вопрос?

My CustomCell



public class DiscoverySmallCollectionCell: UICollectionViewCell {


    public var mainView : DiscoveryNavigationCard


    public init(image: UIImage) {
        self.mainView = DiscoveryNavigationCard(largeImage: image)
        super.init(frame: CGRect.zero)
        self.translatesAutoresizingMaskIntoConstraints = false
        setup()
    }

    override public init(frame: CGRect) {
        self.mainView = DiscoveryNavigationCard()
        super.init(frame: CGRect.zero)
        self.translatesAutoresizingMaskIntoConstraints = false;
        setup()
    }

    public init() {
        self.mainView = DiscoveryNavigationCard()
        super.init(frame: CGRect.zero)
        self.translatesAutoresizingMaskIntoConstraints = false
        setup()
    }

    private func setup(){
        self.addSubview(mainView)
        pinToParent(view: mainView, parent: self)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

MyКонтроллер: Функция Подпись в вопросе:


    private func createColletionViewAndContainer <T>(identifier: String, cellSize: CGSize, cellType: T) where T: UICollectionViewCell {

Функция вызова:


    private func setupCollectionViews(items: [DiscoveryItem]) {

        for item in items {
            let category = item.category
            switch category {
            case "hospital", "favourites":
                self.createColletionViewAndContainer(identifier: category, cellSize: LocalLayout.smallCellSize, cellType: DiscoverySmallCollectionCell )

            default :
                self.createColletionViewAndContainer(identifier: category, cellSize: LocalLayout.largeCellSize, cellType: DiscoveryLargeCollectionCell)

            }
        }
        setup()
    }

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

После небольшого прочтения в превосходном: IOS 12 Основы программирования с помощью Swift Я поймал проблему. Это было связано с синтаксисом.

Аргумент cellType должен быть: T.Type, а не: T.

Правильная подпись:

  private func createColletionViewAndContainer  <T>(identifier: String, cellSize: CGSize, cellType: T.Type) where T: UICollectionViewCell {}

Вызывающий должен предоставить cellType с добавлением .self:

(signature....cellType: SomeClass.self) 

Так что, если Мэтт Нойбург будет там, я приму ваш ответ: P

И большое спасибо всем, кто откликнулся!

0 голосов
/ 09 мая 2019

, если вы хотите настроить многократно используемую ячейку с генериками, это один простой режим:

Первый

настроить универсальную ячейку, в этом примере требуется только один аргумент, но вы можете делать все, что захотите

class GenericCollectionViewCell<U>: UICollectionViewCell {
    var item: U!
}

Секунда

создать UIViewController, который принимает вашу общую ячейку

class GenericViewController<T: GenericCollectionViewCell<U>, U>: UIViewController, UICollectionViewDelegate {
    var items: [U] = []

    fileprivate let cellReuseIdentifier = "GenericCollectionViewCell"

    override func viewDidLoad() {
        collectionView.register(T.self, forCellWithReuseIdentifier: cellReuseIdentifier)
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseIdentifier, for: indexPath) as? GenericCollectionViewCell<U> else { return UICollectionViewCell() }
        cell.item = items[indexPath.item]
        return cell
    }
}

Третий

создает подкласс для вашей общей ячейки и выполняет все ваши настройки

class MySublclassedCollectionViewCell: GenericCollectionViewCell<Whatever> {
  override var item: Whatever! { // see that item becomes of type Whatever
      didSet {
        // setup your cell from here
      }
  }
}

Окончательный

подкласс GenericViewController иработа выполнена

class SublcassedViewController: GenericViewController<GenericCollectionViewCell, Whatever> {
  override func viewDidLoad() {
     super.viewDidLoad()

       self.items = // setup items 
  }
}
...