UICollectionViewDataSource protocol extension for adding default implementations

I have a pretty big application that has many kinds of collections. Most collection views have the same implementation for the data source and Layout Flow delegate (same sizes, fields, etc.). I am trying to create a single protocol that provides standard implementations of UICollectionViewDataSource and UICollectionViewDelegateFlowLayout. Here is my code.

protocol TiledCollectionView{} extension UICollectionViewDataSource where Self: TiledCollectionView{ //default implementation of the 3 methods to load the data ... } extension UICollectionViewDelegateFlowLayout where Self: TiledCollectionView { //default implementation for layout methods to set default margins etc... } class MyViewController: UIViewController, TiledCollectionView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{ // the rest of the required logic for view controller // here I Don't implement any CollectionView methods since I have provided the default implementation already } 

The problem is that the compiler complains that MyViewController does not match the UICollectionViewDataSource. This should not be the case, because I clearly say that add default implementations if the type is TiledCollectionView.

Can anyone help?

+6
source share
3 answers

I know that this is not quite what you asked, I tried - it did not work. Now looking for a possible answer, because they had a similar situation. But I can offer you such an option, how to hide in your user protocol all the logic for implementing delegation / dataSource.

 class CollectionViewProtocolHandler: NSObject, UICollectionViewDelegate, UICollectionViewDataSource { func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 0 } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { return UICollectionViewCell() // only for test } } protocol CollectionViewProtocol { var handler: CollectionViewProtocolHandler! {get set} mutating func useProtocolForCollectionView(collectionView: UICollectionView) } extension CollectionViewProtocol { mutating func useProtocolForCollectionView(collectionView: UICollectionView) { handler = CollectionViewProtocolHandler() collectionView.delegate = handler collectionView.dataSource = handler } } class ViewController: UIViewController, CollectionViewProtocol { var handler: CollectionViewProtocolHandler! // CollectionViewProtocol convenience override func viewDidLoad() { super.viewDidLoad() let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: UICollectionViewFlowLayout()) collectionView.backgroundColor = .redColor() view.addSubview(collectionView) var reference = self reference.useProtocolForCollectionView(collectionView) // for initialize protocol } } 
+5
source

I expect the problem is that it is an Objective-C protocol. Objective-C has never heard of protocol extensions. Therefore, he does not know that this protocol extension introduces two functions in MyClass. He cannot see them, and as far as is known, the protocol requirements are not met.

+4
source

To add, but change, what katleta3000 answered, you can restrict the protocol to only applicable to the class

  CollectionViewProtocol: class 

so you don't need 'useProtocolForCollectionView:' be mutating

What then makes it so that you do not need it is var reference = self , and you can simply say self.userProtocolForCollectionView(collectionView)

Especially if you plan to implement this protocol only with NSObject or class types (UIViewController, UICollectionView, etc.)

+1
source

All Articles