UICollectionView in a UICollectionViewCell

最后都变了- 提交于 2019-12-03 06:36:03

There's an article that Ash Furrow wrote that explains how to put an UICollectionView inside an UITableViewCell. It's basically the same idea when using it inside an UICollectionViewCell.

Everything is done programatically. No storyboards.

I added a UICollectionView inside my UICollectionViewCell. I also show how to add again a UICollectionViewCell inside the created UICollectionView to have this result

import UIKit

class CategoryCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    private let cellId = "cell"

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    let appsCollectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        return collectionView
    }()

    func setupViews() {
        backgroundColor = .blue

        addSubview(appsCollectionView)

        appsCollectionView.delegate = self
        appsCollectionView.dataSource = self
        appsCollectionView.register(AppCell.self, forCellWithReuseIdentifier: cellId)

        addConstrainstWithFormat("H:|-8-[v0]-8-|", views: appsCollectionView)
        addConstrainstWithFormat("V:|[v0]|", views: appsCollectionView)

    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 5
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
        return cell
    }
}

class AppCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupViews(){
        backgroundColor = .red
    }
}

My UICollectionViewController

import UIKit

class FeaturedAppsController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    let cellId = "cell"

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        collectionView?.backgroundColor = .white
        collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: cellId)
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(view.frame.width, 150)
    }

}

The whole explanation can be found and was developed by "Let´s build that app": https://www.youtube.com/watch?v=Ko9oNhlTwH0&list=PL0dzCUj1L5JEXct3-OV6itP7Kz3tRDmma

This is too late for this answer but it might help others. This is an example of UICollectionView inside a UICollectionViewCell.

Lets start by having a mainCollectionView. Then on each cell of this collection create and initialize a new UICollectionView and right place to do that is in this following delegate of UICollectionView

func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath)

e.g I initialize the MainCollectionViewCell here and then MainCollectionViewCell handles the logic to create a new UICollectionView

guard let collectionViewCell = cell as? MainCollectionViewCell else { return }

    collectionViewCell.delegate = self

    let dataProvider = ChildCollectionViewDataSource()
    dataProvider.data = data[indexPath.row] as NSArray

    let delegate = ChildCollectionViewDelegate()

    collectionViewCell.initializeCollectionViewWithDataSource(dataProvider, delegate: delegate, forRow: indexPath.row)

    collectionViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0

Here is the initializer on MainCollectionViewCell that creates a new UICollectionView

func initializeCollectionViewWithDataSource<D: protocol<UICollectionViewDataSource>,E: protocol<UICollectionViewDelegate>>(dataSource: D, delegate :E, forRow row: Int) {

    self.collectionViewDataSource = dataSource

    self.collectionViewDelegate = delegate

    let flowLayout = UICollectionViewFlowLayout()
    flowLayout.scrollDirection = .Horizontal

    let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: flowLayout)
    collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseChildCollectionViewCellIdentifier)
    collectionView.backgroundColor = UIColor.whiteColor()
    collectionView.dataSource = self.collectionViewDataSource
    collectionView.delegate = self.collectionViewDelegate
    collectionView.tag = row

    self.addSubview(collectionView)

    self.collectionView = collectionView

    collectionView.reloadData()
}

Hope that helps !!

I did an example for this and put in on github. It demonstrates the use UICollectionView inside a UICollectionViewCell.

https://github.com/irfanlone/Collection-View-in-a-collection-view-cell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!