-1

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

我试图使视图居中(水平),到视图顶部的距离为 10 pts,并具有旋转支持。

应用程序架构有常规的东西,如下(没有故事板):

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

鉴于在横向模式下,statusBar不可见并且为了简化自动布局配置,我决定添加一个顶部锚点navigationBar如下(为了清晰起见,代码被简化):

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

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

肖像 在此处输入图像描述

景观 在此处输入图像描述

现在。GitHub 中的 FastForward 1 提交,整体 App View 架构没有变化,代码相同,它崩溃并显示以下消息

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

知道这里可能会发生什么吗?我从以前的 GitHub 提交中下载了 .zip 以将其隔离并重新确认它是否有效!!。但是当前提交失败,没有对与 this 相关的代码进行任何更改UILabel

导航栏是UIWindow-> UILayoutContainerView->的一部分UINavigationBar

  • 为什么 Xcode 抱怨 NSLayoutYAxisAnchor 锚?(我只有centerX和top anchors)
  • 为什么 navBar.bottomAnchor 的 label.topAnchor 在之前的提交中有效(即使它们不在同一个视图层次结构中)?
4

1 回答 1

0

我能够确定导致崩溃的原因。

最后一次提交的唯一区别是一个小的延迟(在添加 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
        }
    }
}

您将在这里找到一个带有工作代码的干净 Xcode 项目https://www.dropbox.com/s/vhd9emd8ixf5lbs/AutoLO.zip?dl=0

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

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

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

于 2018-07-20T20:42:25.130 回答