ios - 从不同 View Controller 添加 3D 对象时,Swift ARKit SceneView nil

标签 ios swift augmented-reality

在我的 Storyboard中,我有 2 个简单的 viewController。在应用程序启动时显示的 View ,具有简单的布局,其中包含一个按钮。单击按钮时,通过显示包含 ARSCNView 的第二个 viewController 来继续。

    @IBOutlet weak var sceneView: ARSCNView!

在 viewDidLoad 中,我可以添加 3D 对象,还可以使用 touchBegin 在平面上点击时显示其他 3D 对象。效果很好。

但是,我的第一个 viewController 需要根据第一个 viewController 中发生的某些委托(delegate)触发将 3D 对象添加到场景中。第一个 viewController 只是调用第二个 viewController 上的函数来添加 3D 对象(与我在平面上点击时添加 3D 对象的函数相同)。

    secondViewController.add3DObject()

当它从我的第一个 viewController 调用 add3DObject 时,sceneView 为零。

当我能够添加由第二个 viewController 触发的 3D 对象时,为什么我无法通过不同的 viewController 触发相同的事情?

第一个viewController:(省略与问题无关的整堆代码)

    class ViewController: UIViewController, CLLocationManagerDelegate {

       var locationManager = CLLocationManager()
       var arSceneViewController = ARSceneViewController() //second viewController

        func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
         // omitting some logic here....
         // call a function in second view controller
         arSceneViewController.addARItems(item: item)
        }
    }

第二个viewController:(省略与问题无关的整堆代码)

    class ARSceneViewController: UIViewController, ARSCNViewDelegate {

        @IBOutlet weak var sceneView: ARSCNView!

         // this works 
         override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
             if let touch = touches.first{
             let touchLocation = touch.location(in: sceneView)

             let results = sceneView.hitTest(touchLocation, types: .existingPlaneUsingExtent)
             var arItem = ARItem()
             arItem.itemDescription = "hello"
            if let hitResult = results.first{
                // calling this works from here
                addARItems(item: arItem ,atLocation: hitResult)
            }
        }
      }

    // Called from first ViewController doesn't work
    // Called from the same file work (from touchesBegin)
    func addARItems(item: ARItem, atLocation location:ARHitTestResult? = nil){
        // sceneView is nil!!!
        guard let sView =  sceneView else { return }       

        // omitted some insignificant code here ...

        let cube = SCNBox(width:0.5, height: 0.1, length: 0.1, chamferRadius: 0.01)
        let node = SCNNode()
        node.position = SCNVector3(0, 0.1, -0.5)
        node.geometry = cube

        sceneView.scene.rootNode.addChildNode(node)
    }

}

最佳答案

正如所讨论的,我希望这段代码适合您。

当单击按钮时,通过显示包含 ARSCNView 的第二个 viewController 来继续。 --> 因此,我们将通过覆盖 func prep for segue 来获取第二个 View Controller (请将“第二个 View Controller 的第二个 View Controller 的 segue id”替换为您在 Storyboard中设置的实际标识符)。

在委托(delegate) locationManager didUpdateHeading 中,我们将检查第二个 View Controller 是否存在,然后调用 addARItems

var arSceneViewController: ARSceneViewController? //second viewController

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "your segue id for second view controller" {
        arSceneViewController = segue.destination as? ARSceneViewController
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
    // omitting some logic here....
    // call a function in second view controller
    if let arSceneVC = arSceneViewController {
         arSceneVC.addARItems(item: item)
    }
}

关于ios - 从不同 View Controller 添加 3D 对象时,Swift ARKit SceneView nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56729333/

相关文章:

ios - 核心数据类的全局变量(坏?好?)

ios - WebRTC iOS : Audio/Video stream recording

ios - 如何将 UIButton 带到 Mapbox View 的前面

ios - 如何添加阴影平面以及苹果提供的和我们创建的.scn文件的区别

Android compass 精度 - 何时校准?

c++ - 将 CMSampleBufferRef 转换为 cv::Mat

ios - 如何知道 WKContentRuleList 阻止了什么

ios - jquery 移动绑定(bind)/实时点击

ios - 快速更改 View 时的动画

android - Appcelerator/Phonegap 中具有运行时覆盖的相机 View ?可能的?