Search code examples
swiftgenericspolymorphismuicollectionviewcell

Subclasses of UICollectionviewcell fail to be implemented as generics


I'm looking to dynamically crate some collectionviews.

When calling my factory function I want to pass it a Subclassed Type of a UICollectionViewCell. I'm using Typed generics to get this done. However the compiler is stopping me and making me question my understanding of polymorphism in Swift.

Could anybody shed some light on the matter?

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 Controller: Function Signature in question:


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

Calling fucntion:


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

Solution

  • After A little bit of reading in the excellent: IOS 12 Programming fundamentals with Swift i've caught the issue. It was Syntax-related.

    The argument cellType needed to be: T.Type, not: T.

    The correct signature is:

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

    The caller should supply cellType with .self appended:

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

    So if Matt Neuburg is out there: I'll accept you answer :P

    And a big thanks to everybody that responded!