两个视图控制器之间共享的SCNNode消失

时间:2016-07-30 00:01:19

标签: ios swift scenekit

我有一个非常大的(500mb).dae文件需要几秒钟加载,所以我在后台加载一次并在两个相同的视图控制器中重复使用它。第一个控制器显示模型正常,但是当我模态地呈现下一个视图控制器(也显示模型正常)并将其关闭时,模型消失,从第一个视图控制器的场景中移除。当SCNView被清理时,SceneKit是否尝试处理节点?我不确定我还能解释发生了什么,因为两个视图控制器是同一个类的两个实例,用作子视图控制器。

// CarLoader.swift
class CarLoader {
    private static let instance = CarLoader();

    var storedCar: SCNNode = SCNNode();
    var loaded: Bool = false;
    var onReady:(car: SCNNode)->() = { (car: SCNNode) in } ;

    private init(){}

    class func load( onLoad: ()->() ){
        if CarLoader.instance.loaded {
            onLoad();
            return;
        }
        dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)) {
            let scene = SCNScene(named: "Scenes.scnassets/export_test6.dae");
            dispatch_async(dispatch_get_main_queue()) { // 2
                let nodeArray = scene!.rootNode.childNodes;
                let centeringNode = SCNNode();
                for childNode in nodeArray {
                    centeringNode.addChildNode(childNode as SCNNode)
                }

                centeringNode.eulerAngles.x = -Float(M_PI/2);

                var min = SCNVector3(), max = SCNVector3();
                let _ = centeringNode.getBoundingBoxMin(&min, max: &max);

                let w = CGFloat(abs(max.x - min.x));
                let h = CGFloat(abs(max.y - min.y));
                //let l = CGFloat(abs(max.z - min.z));

                centeringNode.position.x = -min.x + -Float(w/2);
                centeringNode.position.y = -min.y/2 + -Float(h/2); // it's still a little low in y, but we want it lower
                centeringNode.position.z = 0;

                CarLoader.instance.storedCar = centeringNode;
                CarLoader.instance.loaded = true;
                CarLoader.instance.onReady(car: centeringNode);
                onLoad();
            }
        }
    }
    class func cachedModel( onReady: (car: SCNNode) -> ()) {
        CarLoader.instance.onReady = onReady;
        if CarLoader.instance.loaded {
            CarLoader.instance.onReady(car: CarLoader.instance.storedCar);
        }
        else {
            // callback is called when ready
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我最终通过命名并在ViewDidAppear期间检查它是否存在来解决它。

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated);
    // the car disappears in the Explorer when it reappears after the settings menu has been up
    if self.carRootNode.childNodeWithName(CarLoader.CarModelNodeName, recursively: false) == nil {
        self.insertCarModel();
    }
}