SwiftUI - how to add a Scenekit Scene

泄露秘密 提交于 2020-05-10 03:38:25

问题


How can I add a Scenekit Scene to a SwiftUI view?

I tried the following Hello World, using the standard Ship Scene example...

import SwiftUI
import SceneKit


struct SwiftUIView : View {
    var body: some View {

       ship()

        Text("hello World")


    }

But it didn't work:


回答1:


In order for this to work, your SwiftUI View must conform to UIViewRepresentable. There's more info about that in Apple's tutorial: Interfacing with UIKit.

    import SwiftUI

struct SwiftUIView : UIViewRepresentable {

    func makeUIView(context: Context) -> UIView {
        return UIStoryboard(name: "Main", bundle: Bundle.main).instantiateInitialViewController()!.view
    }

    func updateUIView(_ view: UIView, context: Context) {

    }
}

#if DEBUG
struct SwiftUIView_Previews : PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}
#endif

Note that you'll have to turn on live preview to see it working.




回答2:


Rawbee's answer does the job if you are creating a SwiftUIView inside a Game project (the default game project that Xcode will create for you)

But if you are in a Single View App project, you can create the same SceneView like this:

First

drag the art.scnassets folder (which contains 2 files: ship.scn and texture.png) from your game project to your Single View App project.

Second

In your Single View App project create a new SwiftUI file — I called it: ScenekitView. This is a structure which conforms to the UIViewRepresentable protocol

Third

Copy and paste the code below to this file and turn on live preview mode

import SwiftUI
import SceneKit

struct ScenekitView : UIViewRepresentable {
    let scene = SCNScene(named: "art.scnassets/ship.scn")!

    func makeUIView(context: Context) -> SCNView {
        // create and add a camera to the scene
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        scene.rootNode.addChildNode(cameraNode)

        // place the camera
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)

        // create and add a light to the scene
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light!.type = .omni
        lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
        scene.rootNode.addChildNode(lightNode)

        // create and add an ambient light to the scene
        let ambientLightNode = SCNNode()
        ambientLightNode.light = SCNLight()
        ambientLightNode.light!.type = .ambient
        ambientLightNode.light!.color = UIColor.darkGray
        scene.rootNode.addChildNode(ambientLightNode)

        // retrieve the ship node
        let ship = scene.rootNode.childNode(withName: "ship", recursively: true)!

        // animate the 3d object
        ship.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: 2, z: 0, duration: 1)))

        // retrieve the SCNView
        let scnView = SCNView()
        return scnView
    }

    func updateUIView(_ scnView: SCNView, context: Context) {
        scnView.scene = scene

        // allows the user to manipulate the camera
        scnView.allowsCameraControl = true

        // show statistics such as fps and timing information
        scnView.showsStatistics = true

        // configure the view
        scnView.backgroundColor = UIColor.black
    }
}

#if DEBUG
struct ScenekitView_Previews : PreviewProvider {
    static var previews: some View {
        ScenekitView()
    }
}
#endif

I'm not a pro but this code worked for me (Xcode 11 beta 4)



来源:https://stackoverflow.com/questions/56743724/swiftui-how-to-add-a-scenekit-scene

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!