由于在iOS中以“不同”视图层次结构定位,自动布局约束会崩溃,但是

时间:2018-07-20 19:35:58

标签: ios swift autolayout anchor uiview-hierarchy

我正在使用 Swift 4.1 的完全编程的 iOS 11.X 应用程序中工作。使用 Xcode 9.4

我正在尝试使一个视图居中(水平)居中,到视图顶部的距离为10 pt,并带有旋转支撑。

应用程序体系结构具有常规内容,如下所示(没有情节提要):

  • 以UIWindow对象和UINavigationController为根的AppDelegate
  • navigationController具有一个UIViewController()作为rootViewController

鉴于在横向模式下statusBar是不可见的,并且为了简化自动布局配置,我决定为navigationBar添加一个顶部锚点,如下所示(为简化起见,对代码进行了简化): / p>

let navBar = self.navigationController!.navigationBar
let label = UILabel()
label.backgroundColor = .yellow
label.text = "TEXT"
label.textAlignment = NSTextAlignment.center
self.view.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.widthAnchor.constraint(equalToConstant: 50).isActive = true
label.heightAnchor.constraint(equalToConstant: 20).isActive = true
label.centerXAnchor.constraint(equalTo: label.superview!.centerXAnchor).isActive = true
label.topAnchor.constraint(equalTo: navBar.bottomAnchor, constant: 10).isActive = true

结果符合预期。它可以很好地旋转,并且如果该应用以横向或纵向(同时在设备和模拟器中)启动,则也可以正常工作。

肖像 enter image description here

景观 enter image description here

现在。在GitHub中进行FastForward 1提交,而整个App View体系结构没有更改,并且代码相同,它崩溃并显示以下消息

*** NSGenericException”,原因:“无法激活具有锚点的约束,因为它们没有共同的祖先。约束或其锚点是否引用了不同视图层次结构中的项目?那是非法的。

对这里可能发生的事情有任何想法吗?我从以前的GitHub承诺中下载了.zip,以使其隔离并再次确认其有效!!但是,当前的提交失败,并且没有更改与此UILabel相关的代码。

navBar是UIWindow-> UILayoutContainerView-> UINavigationBar

的一部分
  • 为什么Xcode抱怨NSLayoutYAxisAnchor锚点? (我只有centerX和顶部锚点)
  • 为什么navBar.bottomAnchor的label.topAnchor在上一次提交中起作用(即使它们不在同一视图层次结构中)?

1 个答案:

答案 0 :(得分:-1)

我能够找出导致崩溃的原因。

最后一次提交的唯一区别是一小段延迟(在添加UI元素和约束之前)。 0.01秒就足够了,它的工作原理如下:

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "APP TITLE"
        self.view.backgroundColor = .white
        Timer.scheduledTimer(withTimeInterval: 0.01, repeats: false) { (nil) in
            let navBar = self.navigationController!.navigationBar
            let label = UILabel()
            label.backgroundColor = .yellow
            label.text = "TEXT"
            label.textAlignment = NSTextAlignment.center
            self.view.addSubview(label)
            label.translatesAutoresizingMaskIntoConstraints = false
            label.widthAnchor.constraint(equalToConstant: 50).isActive = true
            label.heightAnchor.constraint(equalToConstant: 20).isActive = true
            label.centerXAnchor.constraint(equalTo: label.superview!.centerXAnchor).isActive = true
            label.topAnchor.constraint(equalTo: navBar.bottomAnchor, constant: 10).isActive = true
        }
    }
}

您将在https://www.dropbox.com/s/vhd9emd8ixf5lbs/AutoLO.zip?dl=0

中找到一个包含工作代码的干净Xcode项目。

注释Timer.scheduledTimer(withTimeInterval:repeats :)行,它将崩溃,并显示以下消息:

***由于未捕获的异常“ NSGenericException”而终止应用程序,原因:“无法使用锚点NSLayoutYAxisAnchor:0x60c000267e80“ UILabel:0x7fe0ede0b960'TEXT'.top”和NSLayoutYAxisAnchor:0x60c000267f00“ UINavigationBar:0x7fe0tomedd06”来激活约束。他们没有共同的祖先。约束或其锚点是否引用了不同视图层次结构中的项目?那是非法的。

为什么Xcode在没有中心中心时会抱怨centerY / YAxis锚点的解释对我来说还是个谜。

相关问题