7

The problem occurs when I put VideoPlayer view inside NavigationView's parent view or child view. In this example the child view will show navigation bar:

struct ParentView: View {
  var body: some View {
    NavigationView {
      VStack {
        Text("Parent View")

        NavigationLink(destination: ChildView().navigationBarHidden(true)) {
          Text("Child View")
        }
      }
      .navigationBarHidden(true)
    }
  }
}

struct ChildView: View {
  var body: some View {
    VStack {
      Text("Child View")
      VideoPlayer(player: AVPlayer())
    }
  }
}
egeeke
  • 753
  • 1
  • 6
  • 18
netsplatter
  • 559
  • 3
  • 14

2 Answers2

4

I was having the same issue. Not sure what's causing it but I ended up replacing the VideoPlayer with a custom one. That removed the space on top.

  struct CustomPlayer: UIViewControllerRepresentable {
  let src: String

  func makeUIViewController(context: UIViewControllerRepresentableContext<CustomPlayer>) -> AVPlayerViewController {
    let controller = AVPlayerViewController()
    let player = AVPlayer(url: URL(string: src)!)
    controller.player = player
    player.play()
    return controller
  }

  func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<CustomPlayer>) { }
}

And in your view where you want to use it, do:

CustomPlayer(src: "<the source to the video>")
egeeke
  • 753
  • 1
  • 6
  • 18
Inna B
  • 71
  • 3
  • Thank you! This solution works. But I got another problem with CustomPlayer - it doesn't work with dynamic source. I tried to pass AVPlayer instead of src, but still looking for solution to make it update the source on change. – netsplatter Apr 08 '21 at 18:05
2

if you want a custom player with the same initializer as the native one and that updates along with the current state of the application:

struct CustomPlayer: UIViewControllerRepresentable {
    let player: AVPlayer

    func makeUIViewController(context: UIViewControllerRepresentableContext<CustomPlayer>) -> AVPlayerViewController {
        let controller = AVPlayerViewController()
        controller.player = player
        return controller
    }

    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<CustomPlayer>) {
        uiViewController.player = player
    }
}

note that on updateUIViewController(_: context:) you should update the view with every variable you declared and expect to update