如何将SCNView更改回UIView?

问题描述 投票:0回答:1

我正在尝试使用Xcode游戏中的代码作为Swift Playground。该代码在Xcode版本中完美运行,但在操场上,我收到错误:

无法将'UIView'(0x114debe38)类型的值转换为'SCNView'(0x12521d3d0)。

类的类型设置为UIViewController类型,所以我不确定为什么这不仅仅在操场上有效。我在应用程序和游乐场都有相同的文件。

我已经看过this question了,但这个方法似乎已经内置了。

我还尝试将它转换回UIView,如果它是SCNView,我也尝试创建一个新视图,将子视图添加为SCNView,然后将最终视图设置为新视图。我的尝试都没有奏效。

class GameScene: UIViewController {

let finalView = UIView()

override func viewDidLoad() {
    super.viewDidLoad()

    // create a new scene
    let scene = SCNScene(named: "art.scnassets/ship.scn")!

    // 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)
    cameraNode.rotation = SCNVector4(0, 0, 0, 30)

    // 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 shark node
    let shark = scene.rootNode.childNode(withName: "ship", recursively: true)!

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

    // retrieve the SCNView
    let scnView = self.view as! SCNView

    // set the scene to the view
    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

    // add a tap gesture recognizer
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
    scnView.addGestureRecognizer(tapGesture)
}

@objc
func handleTap(_ gestureRecognize: UIGestureRecognizer) {
    // retrieve the SCNView
    let scnView = self.view as! SCNView

    finalView.addSubview(scnView)

    // check what nodes are tapped
    let p = gestureRecognize.location(in: scnView)
    let hitResults = scnView.hitTest(p, options: [:])
    // check that we clicked on at least one object
    if hitResults.count > 0 {
        // retrieved the first clicked object
        let result = hitResults[0]

        // get its material
        let material = result.node.geometry!.firstMaterial!

        // highlight it
        SCNTransaction.begin()
        SCNTransaction.animationDuration = 0.5

        // on completion - unhighlight
        SCNTransaction.completionBlock = {
            SCNTransaction.begin()
            SCNTransaction.animationDuration = 0.5

            material.emission.contents = UIColor.black

            SCNTransaction.commit()
        }

        material.emission.contents = UIColor.red

        SCNTransaction.commit()
    }

}

override var shouldAutorotate: Bool {
    return true
}

override var prefersStatusBarHidden: Bool {
    return true
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    if UIDevice.current.userInterfaceIdiom == .pad {
        return .allButUpsideDown
    } else {
        return .all
    }
}
}

PlaygroundSupport.PlaygroundPage.current.liveView = GameScene()

这应该显示的是一个3D模型和一个可以通过移动设备上的触摸平移它的相机。

ios swift xcode scenekit swift-playground
1个回答
0
投票

在您的示例中,UIViewController视图可能已设置为界面构建器中的SCNView。如果你没有使用笔尖,你可以通过覆盖loadView来做到这一点。

  override func loadView() {
    let scnView = SCNView(frame: UIScreen.main.bounds, options: nil)
    self.view = scnView
  }
© www.soinside.com 2019 - 2024. All rights reserved.