首页 > 解决方案 > 如何实现嵌套集合视图?

问题描述

我正在关注这个著名的教程 ,并希望在另一个 collectionView 中实现一个 collectionView。我想我的 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
    }
}

然后:

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

然而 Xcode 很生气:ViewController协议UICollectionViewDataSourceUICollectionViewDelegate. 这是可以理解的,因为我定义了两次..

如何在这里指定内部和外部 collectionViews 的委托方法之间的区别?

标签: iosswiftuicollectionviewuicollectionviewcell

解决方案


当然有冗余,因为这

1-

class ViewController: UIViewController, UICollectionViewDelegate,UICollectionViewDataSource

有了这个

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {

对于这些协议,VC 应该只符合一次

2-

您只需要实现每个方法的一个副本并检查其中的 collectionView 的名称

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

推荐阅读