How can I use SpriteKit with SwiftUI?

I know that now there's a way to integrate SpriteKit with SpriteView, but I'm not using the beta. So, how can i do this?
Answered by dudamello in 635957022
This is how i solved it:
ContentView.swift
Code Block
import SwiftUI
struct ContentView: View {
var body: some View {
SpriteKitContainer(scene: SpriteScene())
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

SpriteKitContainer.swift
Code Block
import SwiftUI
import SpriteKit
struct SpriteKitContainer: UIViewRepresentable {
typealias UIViewType = SKView
var skScene: SKScene!
init(scene: SKScene) {
skScene = scene
self.skScene.scaleMode = .resizeFill
}
class Coordinator: NSObject {
var scene: SKScene?
}
func makeCoordinator() -> Coordinator {
let coordinator = Coordinator()
coordinator.scene = self.skScene
return coordinator
}
func makeUIView(context: Context) -> SKView {
let view = SKView(frame: .zero)
view.preferredFramesPerSecond = 60
view.showsFPS = true
view.showsNodeCount = true
return view
}
func updateUIView(_ view: SKView, context: Context) {
view.presentScene(context.coordinator.scene)
}
}
struct SpriteKitContainer_Previews: PreviewProvider {
static var previews: some View {
Text("Hello, World!")
}
}

SpriteKitScene.swift
Code Block
import UIKit
import SpriteKit
class SpriteScene: SKScene {
//change the code below to whatever you want to happen on skscene
override func didMove(to view: SKView) {
physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let location = touch.location(in: self)
let box = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
box.position = location
box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 50, height: 50))
addChild(box)
}
}

PS: you'll only see the spritekitscene working in the simulator, it won't work in the preview
Hello,

You will need to make use of UIViewRepresentable to create a representable container for your SKView, see this SwiftUI tutorial for an example: https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit
Accepted Answer
This is how i solved it:
ContentView.swift
Code Block
import SwiftUI
struct ContentView: View {
var body: some View {
SpriteKitContainer(scene: SpriteScene())
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

SpriteKitContainer.swift
Code Block
import SwiftUI
import SpriteKit
struct SpriteKitContainer: UIViewRepresentable {
typealias UIViewType = SKView
var skScene: SKScene!
init(scene: SKScene) {
skScene = scene
self.skScene.scaleMode = .resizeFill
}
class Coordinator: NSObject {
var scene: SKScene?
}
func makeCoordinator() -> Coordinator {
let coordinator = Coordinator()
coordinator.scene = self.skScene
return coordinator
}
func makeUIView(context: Context) -> SKView {
let view = SKView(frame: .zero)
view.preferredFramesPerSecond = 60
view.showsFPS = true
view.showsNodeCount = true
return view
}
func updateUIView(_ view: SKView, context: Context) {
view.presentScene(context.coordinator.scene)
}
}
struct SpriteKitContainer_Previews: PreviewProvider {
static var previews: some View {
Text("Hello, World!")
}
}

SpriteKitScene.swift
Code Block
import UIKit
import SpriteKit
class SpriteScene: SKScene {
//change the code below to whatever you want to happen on skscene
override func didMove(to view: SKView) {
physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let location = touch.location(in: self)
let box = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
box.position = location
box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 50, height: 50))
addChild(box)
}
}

PS: you'll only see the spritekitscene working in the simulator, it won't work in the preview
How can I use SpriteKit with SwiftUI?
 
 
Q