ios - 如何实现嵌套 Collection View ?

标签 ios swift uicollectionview uicollectionviewcell

我正在关注这个著名的tutorial 并希望在另一个 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 与协议(protocol) UICollectionViewDataSourceUICollectionViewDelegate 的冗余一致性。这是可以理解的,因为我定义了两次..

如何在此处指定内部和外部 CollectionView 的委托(delegate)方法之间的差异?

最佳答案

当然存在冗余,因为这

1-

class ViewController: UIViewController, UICollectionViewDelegate,UICollectionViewDataSource

有了这个

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {

VC 应该只符合这些协议(protocol)一次

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

关于ios - 如何实现嵌套 Collection View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50769718/

相关文章:

iOS长时间运行的后台定时器, "location"后台模式

ios - 如何向用户呈现警报?

ios - 如何在 Swift 中使用 slider 值更改 kCIInputBrightnessKey,无论 slider 获得什么值,我都会得到白色或黑色图片

xcode - Mac OSX 上的 UICollectionView 等价物

ios - Swift 3.0 中的 NSIndexPath 和 IndexPath

ios - 更改权限时应用程序在后台崩溃 - swift

iphone - 如何在 iOS 中读取音频文件并获取样本?

objective-c - UITextField 绑定(bind)

ios - 改变声音以匹配不同的倍数

ios - 通过主视图 Controller 与 UICollectionViewCell 中的按钮交互