Scene Editor Development: Showing a SwiftUI View Based on a Selection
The inspector for the scene editor has separate SwiftUI views for each kind of item in a SpriteKit scene. There’s a sprite inspector for sprites, a label inspector for labels, and so on.
When someone selects an item from the scene graph, the inspector should show the correct view. If someone selects a sprite, the inspector view should show the sprite inspector. How do you show the correct view based on the selection?
My solution is to get the class name for the selected item, add a switch
statement to the view body, and show the correct view based on the class name.
Getting the Class Name
The inspector has a property that contains the selected item from the scene graph.
@State var node: SKNode
Because each kind of item in a SpriteKit scene has its own class, I can get the name of the class for the node
property and show the correct view based on the name of the class.
NSObject
is the base class for every SpriteKit class. The NSObject
class has a nameOfClass
property for Mac, but not iOS. But I saw on Stack Overflow that you can add an extension to NSObject
to get the name of the class on iOS.
public extension NSObject {
class var nameOfClass: String {
return NSStringFromClass(self).components(separatedBy: ".").last!
}
var nameOfClass: String {
return NSStringFromClass(type(of: self)).components(separatedBy: ".").last!
}
}
Adding a Switch Statement to the SwiftUI View
Now that I can get the names of the SpriteKit classes, I can add a switch
statement in the SwiftUI view body and show the correct view based on the class of the selected item in the scene graph.
struct Inspector: View {
@State var node: SKNode
var body: some View {
switch node.nameOfClass {
case "SKSpriteNode":
SpriteInspector(node: node as! SKSpriteNode)
case "SKLabelNode":
LabelInspector(node: node as! SKLabelNode)
case "SKLightNode":
LightInspector(node: node as! SKLightNode)
// Other SpriteKit classes go here.
default:
EmptyView()
}
}
}
I can safely cast with as!
because I know the class of the selected item.