Reputation: 3147
I have a UICollectionViewCell subclass that implements a protocol like so:
protocol SpecialCell where Self: UICollectionViewCell {
associatedType T: SpecialCellViewModel // protocol
var viewModel: T? { get set }
}
When dequeuing the cell I have to cast the UICollectionViewCell to my SpecialCell conforming type in order to access the viewModel property. I am trying it like this:
let cell = collectionView.dequeueReusableCell[...]
(cell as? SpecialCell).viewModel = viewModel[...]
Now the second line here causes the compiler to throw the 'can only be used as a generic constraint[...]' error message, although the protocol practically guarantees that Self must be of type UICollectionViewCell. Why do I still get this error message and is there any other approach to this?
Upvotes: 0
Views: 48
Reputation: 1479
You can't use a variable with a protocol type which has an associatedType
because the Swift compiler doesn't know what the associated type is (it just knows it has a T
type which conforms to some protocol, but it doesn't know what type that T
is exactly). You must use a concrete type (a class which conforms to SpecialCell
protocol) which has a concrete associated type for your generic parameter of the SpecialCell
protocol.
Also, in my opinion I don't think there is any use to enforce where Self: UICollectionViewCell
. You have to create a UICollectionViewCell
subclass that conforms to SpecialCell
anyway to use your protocol.
I am guessing that you have several subclasses of cell that conform to SpecialCell
and this is the reason you want to write your code this way. Unfortunately there is no way to do this in Swift, other than casting each dequeued cell to its concrete type when using a protocol with associatedType
.
Upvotes: 1