Sharad Chauhan
Sharad Chauhan

Reputation: 4891

Multiple collectionViews in single TableCell

I am planning to take multiple collectionView inside single tableView Cell.

What I really want is to show album photos in this manner (UI is important). See image:

enter image description here

how can make this UI ?

Till now I have take a TableView -> TableCell (Single) -> 3 different collectionView inside cell.

Code:

CustomGalleryController

class CustomGalleryController: UIViewController {

    var arrayOfPHAsset = [PHAsset]()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        CustomAlbum().fetchCustomAlbumPhotos { (array) in
            self.arrayOfPHAsset = array
            CustomGalleryTableCell().firstCollectionArray  = array
            CustomGalleryTableCell().secondCollectionArray = array
            CustomGalleryTableCell().thirdCollectionArray  = array
            //self.collectionView.reloadData()
        }



    }

extension CustomGalleryController : UITableViewDelegate{

}

extension CustomGalleryController : UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomGalleryTableCell", for: indexPath) as! CustomGalleryTableCell

        return cell
    }
}

CustomGalleryTableCell

class CustomGalleryTableCell: UITableViewCell {


    @IBOutlet var firstCollectionView: UICollectionView!
    @IBOutlet var secondCollectionView: UICollectionView!
    @IBOutlet var thirdCollectionView: UICollectionView!

    var firstCollectionArray = [PHAsset]()
    var secondCollectionArray = [PHAsset]()
    var thirdCollectionArray = [PHAsset]()

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

extension CustomGalleryTableCell : UICollectionViewDataSource{

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//        if collectionView == firstCollectionView {
//            return 1;//firstCollectionArray.count
//        }else if collectionView == secondCollectionView {
//            return 1;//secondCollectionArray.count
//        }else{
//            return 1;//thirdCollectionArray.count
//        }
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if collectionView == firstCollectionView {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FirstCollectionCell", for: indexPath) as! FirstCollectionCell

            return cell
        }else if collectionView == secondCollectionView {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SecondCollectionCell", for: indexPath) as! SecondCollectionCell

            return cell
        }else{
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ThirdCollectionCell", for: indexPath) as! ThirdCollectionCell

            return cell
        }
    }
}

But getting crash:

Terminating app due to uncaught exception NSInvalidArgumentException', reason: '-[UITableView collectionView:numberOfItemsInSection:]: unrecognized selector sent to instance 0x1049ed600

po 0x1049ed600 gives:

<UITableView: 0x1049ed600; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x17424b550>;

layer = ; contentOffset: {0, 0}; contentSize: {414, 44}>

  1. Please suggest any other and good way to achieve this UI?
  2. What may be the cause of crash if my way of making this UI is correct?

Upvotes: 0

Views: 893

Answers (3)

Furzy
Furzy

Reputation: 1

Beginner with swift and Xcode here. I've been looking for a solution to populate two CollectionView in a single TableViewCell. Even though this might not exactly be appropriate for your case, the title of your question matches :-) Finally managed to do it by using the tag attribute in the storyboard.

Here's how I did it:

  • First give a tag number to each CollectionView in the storyboard
  • In your ViewControllerDataSource, check if it's the right CollectionView by using an if statement and return whatever's needed (numberOfItemsInSection, cellForItemAt).

    extension ViewController: UICollectionViewDataSource {
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            if collectionView.tag == 0 {
                return imageArray1.count
            } else {
                return imageArray2.count
            }
        }
    }
    

Hope this helps!

Upvotes: 0

Ahmad F
Ahmad F

Reputation: 31645

Please suggest any other and good way to achieve this UI?

If you are aiming to achieve what are you mentioning the in screenshot, there is no need to implement it as a tableview which contains collectionviews, instead, the straightforward way to work with UICollectionViewLayout.

As a tip, for the purpose of saving some time and effort, you could find a library that can do the job for you, such as:

Or if you are interested in reordering the items:

Upvotes: 1

Dejan Skledar
Dejan Skledar

Reputation: 11435

This would achievable using the CHTCollectionViewWaterfallLayout made by chiahsien. I already used this library and I must say it works really great.

You can install it using pods:

pod 'CHTCollectionViewWaterfallLayout/Swift'

The Demo in Swift can be found here.

The only thing different from this example is that you have a certain padding on each column on the top, but I'm sure this is achievable also.

Upvotes: 1

Related Questions