Search code examples
swiftuicollectionviewuicollectionviewcellavplayer

passing an AVPlayerLayer reference up heirarchy


I have an AVPlayer located in a collectionView cell, that's in a collectionView, that is located in a collectionView cell.

So to recap, each one of my cells has a collection view in them. Inside that collection view are three cells. One of which contains the AVPlayer.

I want it so that when the user taps on the player, the video within the cell animates to envelope the entire screen.

I initially tried to access keywindow from within the cell, however, because of where the player is located in the view hierarchy. It cannot exceeded the bounds of the collectionView that it's located in.

What was initially recommended to me was to, when tapped, delete the AVPlayer and pass the PlayerLayer's reference to the root view controller. However, I am having trouble in doing so. This is the first time I've had to send a reference "up" in a hierarchy.

So I guess the main question is:

How exactly do I send the playerLayers reference up in the view hierarchy.

also is it possible to reference the playerLayers initial location before tapped so that I may animate the transition seamlessly.

Any suggestions?


Solution

  • How exactly do I send the playerLayers reference up in the view hierarchy.

    Through delegation. When a CollectionViewCell is tapped, the didSelectItemAt(IndexPath) delegate function is called. Your AVPlayer should be in some custom cell (AVPlayerCVCell for this example) and it has an AVPlayer property. Check that the selected cell was an AVPlayerCVCell, and then you can set your root view controller's single AVPlayer to be that of the cell. (May have to set that cell's player to nil or some other form of clean up). Note: Following syntax might be slightly off, but all things highly documented in the Apple UICollectionView docs.

    func collectionView(UICollectionView, didSelectItemAt: IndexPath){
        if let playerCell = collectionView.cellForRowAt(indexPath) as? AVPlayerCVCell {
            let player = playerCell.player
    
            //Do something with player
            self.mainPlayer = player
        }
    }
    

    Where self is your root controller. Or you can have further layers of delegation, but that would be how to get access to the player.

    As far as animating, I would look into convert(rect: to view:) to convert one views coordinate system into another. You can get the cells coordinates relative to your root controller, set the root controllers main avPlayer frame to that rect, than animate out to full screen.