由于未捕获的异常“ NSGenericException”而终止应用程序,原因:“无法使用锚点激活约束

时间:2019-08-20 01:35:16

标签: ios swift constraints

我试图找到并考虑这个问题,我找不到解决该问题的最佳解决方案!!而且我不明白这是什么意思!!

  

由于未捕获的异常“ NSGenericException”而终止应用程序,原因:“无法激活具有锚点的约束,并且因为它们没有共同的祖先。约束或其锚点是否引用了不同视图层次结构中的项目?那是非法的。'

代码:

private let logoImageView: UIImageView = {
    let imgView = UIImageView()
    imgView.image = UIImage(named: "LogoBlue")
    return imgView
}()

func setupLogo() {

    if #available(iOS 11.0, *) {
        view.add(subview: logoImageView) { (v, p) in [
            v.topAnchor.constraint(equalTo: p.safeAreaLayoutGuide.topAnchor, constant: 50),
            v.centerXAnchor.constraint(equalTo: p.centerXAnchor),
            v.heightAnchor.constraint(equalTo: p.widthAnchor, multiplier: 0.5),
            v.widthAnchor.constraint(equalTo: p.widthAnchor, multiplier: 0.5)
        ]}
    } else {
        view.add(subview: logoImageView) { (v, p) in [
            v.topAnchor.constraint(equalTo: p.topAnchor, constant: 50),
            v.centerXAnchor.constraint(equalTo: p.centerXAnchor),
            v.heightAnchor.constraint(equalTo: p.widthAnchor, multiplier: 0.5),
            v.widthAnchor.constraint(equalTo: p.widthAnchor, multiplier: 0.5)
        ]}
    }
}

扩展名:

extension UIView {
    func add(subview: UIView, createConstraints: (_ view: UIView, _ parebt: UIView) -> [NSLayoutConstraint]) {
        subview.activate(constraints: createConstraints(subview, self))
    }

    func activate(constraints: [NSLayoutConstraint]) {
        translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate(constraints)
    }
}

1 个答案:

答案 0 :(得分:2)

您需要在应用约束之前在层次结构上添加UIView

换句话说,您需要<#PARENT_HERE#>.addSubview(<#CHILD_HERE#>)

您可以将扩展名更改为:

extension UIView {
    func add(subview: UIView, createConstraints: (_ view: UIView, _ parebt: UIView) -> [NSLayoutConstraint]) {
        self.addSubview(subview) // <
        subview.activate(constraints: createConstraints(subview, self))
    }

    func activate(constraints: [NSLayoutConstraint]) {
        translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate(constraints)
    }
}

如果您可以修改扩展名,这绝对是我的解决方案。


另一种不太喜欢的解决方案是在扩展程序之外手动添加每个子视图:

func setupLogo() {
    self.view.addSubview(logoImageView) // assuming self.view is not nil
    if #available(iOS 11.0, *) {
        view.add(subview: logoImageView) { (v, p) in [
            v.topAnchor.constraint(equalTo: p.safeAreaLayoutGuide.topAnchor, constant: 50),
            v.centerXAnchor.constraint(equalTo: p.centerXAnchor),
            v.heightAnchor.constraint(equalTo: p.widthAnchor, multiplier: 0.5),
            v.widthAnchor.constraint(equalTo: p.widthAnchor, multiplier: 0.5)
        ]}
    } else {
        view.add(subview: logoImageView) { (v, p) in [
            v.topAnchor.constraint(equalTo: p.topAnchor, constant: 50),
            v.centerXAnchor.constraint(equalTo: p.centerXAnchor),
            v.heightAnchor.constraint(equalTo: p.widthAnchor, multiplier: 0.5),
            v.widthAnchor.constraint(equalTo: p.widthAnchor, multiplier: 0.5)
        ]}
    }
}

注意:这是次要解决方案,请勿同时使用。