Reputation: 645
Maybe I don't understand UIViewRepresentable correctly but I thought this would work.
I'm trying to use two classes that are UIViewRepresentable to display my scnkit scenes in SwiftUI. I also use two coordinator methods for the classes, one each. The coordinator has access to the rendering and physicsWorld methods for the current scene.
The player spawns in the first scene and when contact is made with an enemy, it transitions into the second scene. Here is where the problem starts, it doesn't let the second coordinator handle the physicsWorld and rendering methods for the second class.
I believe it's because I'm still using the first class in swiftui and not the second even though the scene changes. Or in other words, I'm changing scenes but not the class being used.
The Question: How can I transition from the first class to the second and/or from the first scene to the other and still have the coordinator active for each.
Here is the First Class.
struct FirstClass : UIViewRepresentable {
var view = SCNView()
var scene = SCNScene(named: "First.scn")!
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> SCNView {
scene.physicsWorld.contactDelegate = context.coordinator
view.delegate = context.coordinator
return view
}
...
/// Transitions into the second scene.
func changeScenes() {
controlManager.jumped = false
let transition = SKTransition.fade(with: .black, duration: 0.5)
let secondClass = SecondClass()
view.present(secondClass.scene, with: transition, incomingPointOfView: nil)
}
}
Here is the Second Class
struct SecondClass : UIViewRepresentable {
var view = SCNView()
var scene = SCNScene(named: "Second.scn")!
func makeCoordinator() -> SecondCoordinator {
SecondCoordinator(self)
}
func makeUIView(context: Context) -> SCNView {
scene.physicsWorld.contactDelegate = context.coordinator
view.delegate = context.coordinator
return view
}
}
Here is the SwiftUI Class
struct Game: View {
var view = FirstClass()
var body: some View {
ZStack {
view
...
}
}
}
Upvotes: 0
Views: 1043
Reputation: 11
Coordinator
in UIViewRepresentable
is to be used like delegate.
You are not only write:
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
Declare your Coordinator
and make conformance you need.
Don't forget to attach delegate in makeUIView
:
myView.delegate = context.coordinator
Upvotes: 0
Reputation: 32873
This part let secondClass = SecondClass()
won't work, because SwiftUI is not aware about the instance of SecondClass
, in order to properly manage its lifecycle. More, you don't seem to use view
property of the SecondClass
struct (btw, interesting name for a struct :) )
One solution is to manage both scenes within the same UIViewRepresentable
, basically keeping the lifecycle management on the same side.
struct MyScene : UIViewRepresentable {
var view = SCNView()
var firstScene = SCNScene(named: "First.scn")!
lazy var secondScene = SCNScene(named: "Second.scn")!
...
/// Transitions into the second scene.
func changeScenes() {
controlManager.jumped = false
let transition = SKTransition.fade(with: .black, duration: 0.5)
view.present(secondScene, with: transition, incomingPointOfView: nil)
}
}
Upvotes: 0