Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play a video in a carousel when cell is visible

I have something that resembles this:

enter image description here

As you can see, I have a table view, and in each table view cell, I have a collection view. The collection view is horizontal (to replicate a carousel) so that the user can swipe through a gallery of images and videos. Here's another way to picture it:

Controller -> Table View -> Table View Cells -> Collection View (the carousel) -> Collection View Cells (the carousel images/videos)

What I'm trying to achieve is for the video in the carousel to automatically play as the user scrolls through the table view. Of course, for that to happen, the following needs to be done:

  1. Check if the collection view is visible on the screen.
  2. Check if the visible collection view cell is a video (not all cells in the collection view are videos, some are images).
  3. Make sure that two videos in two separate table view cells are not playing at the same time. Only the first visible table view cell should have a playing video.

This, however, is easier said than done. I have previously asked how to determine whether or not a view is visible on the screen, so I know how to do that now.

My question revolves around how I should structure my code.

In my controller class, I have the following:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    isCollectionViewVisible()
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if (!decelerate) {
        isCollectionViewVisible()
    }
}

func isCollectionViewVisible() {
    for visibleCell in self.tableView.visibleCells {
        guard let cell = visibleCell as? MyTableViewCell else {
            continue
        }

        if let myCollectionView = cell.collectionView {
            let visibleRect = self.tableView.bounds
            let myCollectionViewRect = myCollectionView.convert(myCollectionView.bounds, to: tableView)

            if visibleRect.contains(myCollectionViewRect) {
                // Collection view is visible
            } else {
                // Collection view is hidden, either partially or fully
            }
        }
    }
}

So now, when the user scrolls, it checks whether or not the table view cell's collection view is fully visible. How should I proceed from here? How would I tell the first collection view with a visible video to play the video (assume that I have the video code done)?

Secondly, what would be the best way to encapsulate this code (including the above isCollectionViewVisible() function so that I don't have to repeat code in all of my controllers?

Thanks so much!

like image 458
user023425 Avatar asked Dec 12 '19 20:12

user023425


1 Answers

Here’s a work around.

   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

 let cell = tableView.dequeueReusableCell(withIdentifier identifier: “cellIdentifier” for indexPath: indexPath) as! YourTableViewCell


 if cell == tableView.visibleCells.first { // the first element is guaranteed to be fully visible.

        guard let collectionView = cell.collectionView else { return } // to avoid crash when scrolling fast.

           if let videoCell = collectionView.visibleCells.first(where : { cell in cell.hasVideo() }) {
         // however you use to tell if cell has image or video.
           videoCell.play()
          }

       }


    }
like image 105
Celeste Avatar answered Nov 10 '22 01:11

Celeste