Swift ARKit SceneView ноль при добавлении 3D-объекта из другого viewcontroller - PullRequest
0 голосов
/ 24 июня 2019

В моей раскадровке у меня есть 2 простых viewController.Представление, которое появляется в начале приложения с простым макетом, который содержит кнопку.При нажатии на кнопку переходите, показывая второй viewController, в котором находится ARSCNView.

    @IBOutlet weak var sceneView: ARSCNView!

В viewDidLoad я могу добавить 3D-объект, также есть touchBegin для отображения дополнительного 3D-объекта при касании на плоскости.Работает отлично.

Однако мой первый viewController должен инициировать добавление 3D-объекта на сцену после определенного делегата, что происходит в моем первом viewController.Первый viewController просто вызывает функцию на моем втором viewController для добавления 3D-объекта (та же функция, которую я использую для добавления 3D-объекта при нажатии на плоскость).

    secondViewController.add3DObject()

Когда он вызывает add3DObject из моего первого viewController, sceneView равен нулю.

Когда я могу добавить 3D-объект, который запускается вторым viewController, почему я не могу вызвать одно и то же с помощью другого 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)
    }

}

1 Ответ

0 голосов
/ 25 июня 2019

Как уже говорилось, я надеюсь, что этот код работает для вас.

При нажатии на кнопку переходите, показывая второй viewController, в котором находится ARSCNView.-> Таким образом, мы получим второй контроллер представления, переопределив функцию подготовки к segue (пожалуйста, замените «ваш идентификатор segue для второго контроллера представления» на фактический идентификатор, который вы установили в раскадровке).

И в делегате locationManager didUpdateHeading мы проверим, есть ли второй контроллер представления, и затем мы вызываем 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)
    }
}
...