MTKView delegate ownership during view controller transitions

The Problem

When transitioning between view controllers that each have their own MTKView but share a Metal renderer backend, we run into delegate ownership conflicts. Only one MTKView can successfully render at a time, since setting the delegate on one view requires removing it from the other, leading to paused views during transitions.

For my app, I need to display the same visuals across multiple views and have them all render correctly.

Current Implementation Approach

I've created a container object that manages the MTKView and its relationship with the shared renderer:

class RenderContainer {
    let metalView: MTKView
    private let renderer: MetalRenderer
    
    func startRendering() {
        metalView.delegate = renderer
        metalView.isPaused = false
    }
    
    func stopRendering() {
        metalView.isPaused = true
        metalView.delegate = nil
    }
}

View controllers manage the rendering lifecycle in their view appearance methods:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    renderContainer.startRendering()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    renderContainer.stopRendering()
}

Observations & Issues

  • During view controller transitions, one MTKView must stop rendering before the other can start. Also there is no guarantee that the old view will stop rendering before the new one starts, with the current API design.
  • This creates a visual "pop" during animated transitions
  • Setting isPaused = true helps prevent unnecessary render calls but doesn't solve the core delegate ownership problem
  • The shared renderer maintains its state but can only output to one view at a time

Questions

  • What's the recommended approach for handling MTKView delegate ownership during animated transitions?
  • Are there ways to maintain visual continuity without complex view hierarchies?
  • Should I consider alternative architectures for sharing the Metal content between views?

Any insights for this scenario would be appreciated.

Do you get the same results with just the relevant code in a small test project?

If so, please share a link to your test project.

That'll help us better understand what's going on. If you're not familiar with preparing a test project, take a look at Creating a test project.

Albert Pascual
  Worldwide Developer Relations.

MTKView delegate ownership during view controller transitions
 
 
Q