user6724161
user6724161

Reputation: 205

Video view inside xib not stretching to width of controller

I have a collection view that uses a xib for its cells. In that xib, I have a UIView with a custom class, VideoView, which looks like this:

import UIKit
import AVKit
import AVFoundation

/**
 Source: https://medium.com/@rodrigo_freitas/a-simple-ios-view-to-play-video-b7ee05f9ce6a
 */
class VideoView: UIView {

    var playerLayer: AVPlayerLayer?
    var player: AVPlayer?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func configure(url: String) {
        if let videoURL = URL(string: url) {
            player = AVPlayer(url: videoURL)
            playerLayer = AVPlayerLayer(player: player)
            playerLayer?.frame = bounds
            playerLayer?.videoGravity = AVLayerVideoGravity.resizeAspect

            if let playerLayer = self.playerLayer {
                layer.addSublayer(playerLayer)
            }
        }
    }

    func play() {
        if player?.timeControlStatus != AVPlayer.TimeControlStatus.playing {
            player?.play()
        }
    }

    func pause() {
        player?.pause()
    }

    func stop() {
        player?.pause()
        player?.seek(to: CMTime.zero)
    }
}

Here is what my cell xib looks like:

https://i.sstatic.net/xJ4DC.png

As you can see, the constraints are set to the superview (i.e. stretched to full width/height).

The problem is that the video doesn't take up the full width of the collection view controller (the red background is the full cell size):

https://i.sstatic.net/DlH4Q.png

As you can see, the video does not stretch to the full width.

I believe it has to do with the fact that the xib's width and height is a static height (360x640) and this line in the VideoView class is using that width/height to set the size of the video:

playerLayer?.frame = bounds

But I don't know how to change this so that the video matches the width of the collection view controller.

Upvotes: 0

Views: 1824

Answers (3)

tBug
tBug

Reputation: 827

If you have a custom xib.

You will have:

playerLayer = AVPlayerLayer 
mainVideoView: UIView - ( main view is view where video is playing ) 

In viewDidLoad or some custom Func you will have:

    playerLayer.frame = mainVideoView.frame
    playerLayer.videoGravity = .resizeAspectFill

This is my code example: /// Video Player Configuration

func configPlayer(with url: String) {
    guard let url = URL(string: url) else { return }
    let player = AVPlayer(url: url)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = mainVideoView.frame
    playerLayer.videoGravity = .resizeAspectFill
    mainVideoView.layer.addSublayer(playerLayer)
}

Upvotes: 0

Fisky
Fisky

Reputation: 134

You can try:

playerLayer.videoGravity=AVLayerVideoGravityResizeAspectFill

Upvotes: 1

Yasser
Yasser

Reputation: 263

like you said I think the problem is with this line of code:

playerLayer?.frame = bounds

so try giving it a custom CGRect with the same height & width of the view just to make sure it's the source of the problem. if so then change your code to :

playerLayer?.frame = view.frame

I'm not sure where are you getting the "bounds" but the values of it might be wrong that why you're getting the view smaller. Also make sure the collectionCell size is actually big enough to the whole screen to do that use this function, or just adjust the size from the storyboard :

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    return CGSize(width: view.frame.width, height: view.frame.height)

}

I hope this solves your problem.

Upvotes: 0

Related Questions