无法激活具有锚点的约束条件

44

所以,我正在尝试通过编程创建一个场景视图

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}
    }
}

但我得到了这个错误信息:

由于没有共同的祖先,无法激活约束条件 <NSLayoutYAxisAnchor:0x1c0278700 "ARSCNView:0x10690d7e0.top"> 和 <NSLayoutYAxisAnchor:0x1c426db40 "UIView:0x106b14e30.top">。该约束条件或其锚点是否引用位于不同视图层次结构中的项?这是非法操作。

这出现在 \\添加自动布局约束条件 部分。我该如何为该元素添加约束条件?


10
在您可以在它们之间添加约束之前,需要将场景视图作为 self.view 的子视图添加。 - dan
我正在使用委托,检查这部分代码 self.sceneView.delegate = self 并且我正在添加渲染器。 - utiq
2个回答

107

dan is right,在使用锚点之前,您需要将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)

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)
        ])
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接