Невозможно активировать ограничение с помощью якорей

Итак, я пытаюсь создать sceneView программно

class ViewController: UIViewController, ARSCNViewDelegate {
    var sceneView: ARSCNView = ARSCNView()
    let configuration = ARWorldTrackingConfiguration()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin]
        self.configuration.planeDetection = .horizontal
        self.sceneView.session.run(configuration)
        self.sceneView.delegate = self
        self.sceneView.autoenablesDefaultLighting = true

        //add autolayout contstraints
        self.sceneView.translatesAutoresizingMaskIntoConstraints = false
        self.sceneView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
        self.sceneView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
        self.sceneView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
        self.sceneView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

    }

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard anchor is ARPlaneAnchor else {return}
    }
}

Но я получаю это сообщение об ошибке:

Завершение работы приложения из-за необработанного исключения "NSGenericException", причина: "Невозможно активировать ограничение с помощью якорей, и потому что у них нет общего предка. Указывает ли ограничение или его привязки на элементы в разных иерархиях представления? Это незаконно.

Это происходит в части \\add autolayout contstraints, Как я могу добавить ограничения для этого элемента?

2 ответа

Решение

Дэн прав, нужно добавить sceneView как подпредставление, прежде чем вы можете закрепить его. Попробуйте что-то вроде этого:

view.addSubview(sceneView)
sceneView.anchor(top: self.view.topAnchor, left: self.view.leftAnchor, bottom: self.view.bottomAnchor, right: self.view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)

Вот отличное решение для активации ограничения макета с привязками оси макета, которое не загромождает ваш ViewController. Здесь нижний вид — NSView, верхний — SCNView.

      import SceneKit

class ViewController: NSViewController {
    
    lazy var sceneView: SCNView = {
        let sceneView = SCNView(frame: .zero)
        sceneView.allowsCameraControl = true
        sceneView.scene = SCNScene(named: "art.scnassets/ship.scn")!
        return sceneView
    }()
           
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.view.addSubview(sceneView)      // put it first
        self.viewAnchors(sceneView)          // put it next
        
        self.view.subviews.forEach {
            $0.translatesAutoresizingMaskIntoConstraints = false
        }
    }
}

И есть смысл вынести расширение в отдельный .swiftфайл.

      extension ViewController {

    func viewAnchors(_ sv: NSView) {

        NSLayoutConstraint.activate([
            sv.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
            sv.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
            sv.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
            sv.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
        ])
    }
}
Другие вопросы по тегам