Vertical and Horizontal Scrolling When Embedding a Table View in a Collection View that has a Collection View Header and Horizontal Flow Layout

Viewed 907

I am trying to implement an application that allows a user to swipe horizontally between collection view cells while also being able to scroll vertically to see the entire content of a particular cell.

I want all the collection view cells to have a table view embedded within them.

The problem I am running into as of now is that my horizontal scrolling works as I have set the collection view flow layout to horizontal. I know that collection view flow layouts can only support one direction. Because of this, I tried to implement the following solution.

As of now within my project, I have a view controller with a scroll view inside. Embedded within the scroll view, is a collection view. This collection view has its own header implemented via dequeueReusableSupplementaryView.

I know that constraints can often be an issue preventing vertical scrolling to take place so here is a picture of my constraints:

Constraints

Additionally, here is some code that I have used to implement this system:

Determining the scroll view content size

override func viewDidLayoutSubviews() {
    super.viewWillLayoutSubviews()

    scrollView.contentSize.height = collectionView.frame.size.height
    scrollView.contentSize.width = self.view.frame.size.width
}

Setting up the collection view

func setupCollectionView() {
    collectionView.dataSource = self
    collectionView.delegate = self

    collectionView.register(UINib(nibName: "TableViewHolderCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "tableViewHolderCollectionViewCell")
    collectionView.register(UINib(nibName: "CustomCollectionViewHeaderView", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CustomCollectionViewHeaderView")

    collectionView.delaysContentTouches = true
    collectionView.contentInsetAdjustmentBehavior = .never
    collectionView.bounces = false
    collectionView.isPagingEnabled = true

    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    layout.minimumLineSpacing = 0
    layout.sectionHeadersPinToVisibleBounds = true
    layout.sectionInset = UIEdgeInsets(top: 0, left: -self.view.frame.size.width, bottom: 0, right: 0)

    collectionView.setCollectionViewLayout(layout, animated: false)
}

Setting up the collection view data

extension TasksAndScheduleViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 8
    }

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

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

        cell.backgroundColor = colorArray[indexPath.row]

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: 343)
    }

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        //setting up header view

        return headerView
    }
}

After trying to debug, I realized that the collection view vertical scroll might have been overriding the vertical scroll of the scroll view I had added to my view controller. In order to solve this, I created a custom class (as seen below) which my collection view implemented. To my knowledge, this was successful at disabling the vertical scroll for the collection view but it was not successful in enabling the other scroll view's vertical scroll.

class CollectionViewVerticalScroll: UICollectionView {

    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let direction = panGestureRecognizer.direction(in: self)
        if direction.contains(.Down) || direction.contains(.Up) {
            return false
        }
        return true
    }

}

My desired goal is to have the ability to swipe horizontally between these collection view cells that have table views while also being able to vertically scroll the collection view cell and the contents of the table view embedded inside of it. Ideally, the vertical scroll should allow me to scroll the table view cells while also moving the entire view upwards. The closest example to what I am trying to implement that I could find online is twitter's search page. The only difference is that my application has a collection header view and no navigation bar. I have attached a picture below:

Closest Example of What I am trying to replicate (The only difference is that my application has a collection header view and no navigation bar.

I would appreciate any help. Please do let me know if you have any questions or if something doesn't make sense to you.

0 Answers
Related