es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

SwiftUI AVPlayer y AVPlayerLayer durante la recreación de la vista.

Estoy creando una aplicación de Mac OS utilizando SwiftUI.

Tengo un NSViewRepresentable que envuelve al AVPlayer:

class PlaybackModel {
    var player: AVPlayer!
    var playerLayer: AVPlayerLayer!

    func createPlayerLayer() -> AVPlayerLayer {
       let result = AVPlayerLayer(player: self.player)
       result.videoGravity = .resizeAspect
       result.needsDisplayOnBoundsChange = true
       result.backgroundColor = .black

       self.playerLayer = result
   }
}

struct PlayerViewAdapter: NSViewRepresentable {
   let playbackModel: PlaybackModel!

   func makeNSView(context: Context) -> BasePlayerView {
       return BasePlayerView(playbackModel)
   }

   func updateNSView(_ nsView: BasePlayerView, context: Context) {
   }
}

y el BasePlayerView utiliza el AVPlayerLayer como una capa de soporte:

class BasePlayerView: NSView {
   private var playbackModel: PlaybackModel!

   init(_ playbackModel: PlaybackModel) {
       self.playbackModel = playbackModel
       super.init(frame: .zero)

       wantsLayer = true
   }

   override func makeBackingLayer() -> CALayer {
       return playbackModel.playerLayer
   }
}

Inicialmente funciona bien y puedo ver el video reproduciéndose dentro de la vista.

Sin embargo, parece haber un problema durante el proceso de re-renderización de SwiftUI, cuando el método PlayerViewAdapter.makeNSView() se llama nuevamente para el mismo PlaybackModel (debido a cambios de estado), el AVPlayerLayer no se renderiza en el BasePlayerView recién creado.

¿Necesito realizar alguna acción adicional durante esta re-creación de las vistas del reproductor?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, debes actualizar la propiedad playbackModel.playerLayer para que apunte a la nueva capa AVPlayerLayer creada en el método PlayerViewAdapter.updateNSView(). Este método se llama cuando la vista necesita ser actualizada debido a cambios de estado. Puedes hacer esto simplemente llamando a nsView.layer?.addSublayer(playbackModel.playerLayer) para agregar la nueva capa como una subcapa a la capa de la vista.

Comments are closed.