Hey. I am trying to create a present view with a bunch of media (images/videos). Right now I am using a ZStack to render each media and change opacity based on the index selected using a scrollView. The issue seems to be that sometimes, videos don't seem to load in the main slide. There is a slide created as the video exists, the Player shows controls too but doesn't play anything.
Present View Z-Stack
ZStack { ForEach(presentation.slides.indices, id: .self) { index in if let media = mediaCacheManager.mediaCache[index] { if let player = media as? AVPlayer { PlayerView(player: player) .aspectRatio(16/10, contentMode: .fit ) .frame(width: UIScreen.main.bounds.width * 0.8) .background(Color.gray.opacity(0.2)) .clipShape(RoundedRectangle(cornerRadius: 40)) .overlay( RoundedRectangle(cornerRadius: 40) .stroke(Color.gray.opacity(0.5), lineWidth: 1) ) .onDisappear { player.pause() } .opacity(appModel.currentSlide == index ? 1 : 0) } else if let image = media as? Image { image .resizable() .scaledToFit() .frame(width: UIScreen.main.bounds.width * 0.8) .background(Color.gray.opacity(0.2)) .clipShape(RoundedRectangle(cornerRadius: 40)) .overlay( RoundedRectangle(cornerRadius: 40) .stroke(Color.gray.opacity(0.5), lineWidth: 1) ) .padding(.vertical, 10) .opacity(appModel.currentSlide == index ? 1 : 0) } } } }
The PlayerView
public class PlayerUIView: UIView { let playerVC = AVPlayerViewController() let gravity: AVLayerVideoGravity let manageAudio: Bool
override init(frame: CGRect) {
self.gravity = .resizeAspectFill
self.manageAudio = true
super.init(frame: frame)
}
deinit {
if manageAudio {
try? AVAudioSession.sharedInstance().setActive(false)
}
}
init(player: AVPlayer?, gravity: AVLayerVideoGravity, manageAudio: Bool = true) {
self.gravity = gravity
self.manageAudio = manageAudio
super.init(frame: .zero)
guard let player = player else { return }
self.playerSetup(player: player)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func layoutSubviews() {
super.layoutSubviews()
playerVC.view.frame = bounds
playerVC.view.backgroundColor = .clear
playerVC.allowsVideoFrameAnalysis = false
}
private func playerSetup(player: AVPlayer) {
playerVC.updatesNowPlayingInfoCenter = true
playerVC.player = player
playerVC.showsPlaybackControls = true
playerVC.view.backgroundColor = .clear
playerVC.exitsFullScreenWhenPlaybackEnds = true
playerVC.videoGravity = gravity
self.addSubview(playerVC.view)
}
}