Reputation: 4963
I am following this famous tutorial and would like to instead implement a collectionView inside of another collectionView. I think I almost have it with this in my ViewController.swift:
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate,UICollectionViewDataSource {
let model: [[UIColor]] = generateRandomData()
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return model.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "outerCell", for: indexPath) as! OuterCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView,
willDisplay cell: UICollectionViewCell,
forItemAt indexPath: IndexPath){
guard let outerCollectionViewCell = cell as? OuterCollectionViewCell else { return }
outerCollectionViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return model[collectionView.tag].count
}
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",
forIndexPath: indexPath)
cell.backgroundColor = model[collectionView.tag][indexPath.item]
return cell
}
}
Then:
class OuterCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var innerCollectionView: UICollectionView!
func setCollectionViewDataSourceDelegate
<D: UICollectionViewDataSource & UICollectionViewDelegate>
(dataSourceDelegate: D, forRow row: Int) {
innerCollectionView.delegate = dataSourceDelegate
innerCollectionView.dataSource = dataSourceDelegate
innerCollectionView.tag = row
innerCollectionView.reloadData()
}
}
However Xcode is angry: Redundant conformance of ViewController
to protocol UICollectionViewDataSource
and UICollectionViewDelegate
. This is understandable as I am defining it twice..
How do I specify the difference between delegate methods for the inner and outer collectionViews here?
Upvotes: 0
Views: 1316
Reputation: 100503
Sure there is a redundancy because this
1-
class ViewController: UIViewController, UICollectionViewDelegate,UICollectionViewDataSource
with this
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
the VC should conform only once for these protocols
2-
you need to only implement one copy of each method and check the name of the collectionView in it
func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
if collectionView == mainCollectionView {
return model.count // this is the VC collection
}
else {
return model[collectionView.tag].count // cells collection
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == mainCollectionView {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "outerCell", for: indexPath) as! OuterCollectionViewCell
return cell
}
else {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",forIndexPath: indexPath)
cell.backgroundColor = model[collectionView.tag][indexPath.item]
return cell
}
}
func collectionView(_ collectionView: UICollectionView,
willDisplay cell: UICollectionViewCell,
forItemAt indexPath: IndexPath){
if collectionView == mainCollectionView {
guard let outerCollectionViewCell = cell as? OuterCollectionViewCell else { return }
outerCollectionViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)
}
}
Upvotes: 1