Sizing SpriteView inside a List

I am trying to display a SKScene inside a SwiftUI list but I'm having problems getting it to size properly. Here is the code I'm using:

struct MyView: View {
  var scene: SKScene // this is a SKScene with .aspectFit scaling mode
  var body: some View {
    List {
      Section {
        GeometryReader { geo in
          SpriteView(scene: scene, options: [.allowTransparency])
          .frame(height: geo.size.width / scene.size.width * scene.size.height)
        }
      }
      Section {
        Text("SomeOtherStuff")
      }
    }
  }
}

Doing this scales the actual SKScene properly but the list 'cell' doesn't stretch to fit the scene it contains, therefore clipping chunks of said scene. If I drop the GeometryReader and hard code the height, the cell resizes.

My guess is that the SKScene dimensions are not yet available to SwiftUI when the GeometryReader is evaluated.

Any suggestions?

  • It seems GeometryReader itself prevents the list 'cell' from growing. Looking for workarounds.

Add a Comment

Accepted Reply

This seems to yield the desired result. It's not very elegant but it works:

struct MyView: View {
  var scene: SKScene // this is a SKScene with .aspectFit scaling mode
  @State private var scaledHeight = 0.0
  var body: some View {
    List {
      Section {
        SpriteView(scene: scene, options: [.allowTransparency])
        .frame(height: scaledHeight)
        .background(GeometryReader { geo -> Color in
          DispatchQueue.main.async {
            scaledHeight = geo.size.width / scene.size.width * scene.size.height
          }
          return Color.clear
        })
      }
      Section {
        Text("SomeOtherStuff")
      }
    }
  }
}

Replies

This seems to yield the desired result. It's not very elegant but it works:

struct MyView: View {
  var scene: SKScene // this is a SKScene with .aspectFit scaling mode
  @State private var scaledHeight = 0.0
  var body: some View {
    List {
      Section {
        SpriteView(scene: scene, options: [.allowTransparency])
        .frame(height: scaledHeight)
        .background(GeometryReader { geo -> Color in
          DispatchQueue.main.async {
            scaledHeight = geo.size.width / scene.size.width * scene.size.height
          }
          return Color.clear
        })
      }
      Section {
        Text("SomeOtherStuff")
      }
    }
  }
}