Swift 5: centerXAnchor 不会在视图中居中我的框架

Swift 5: centerXAnchor won't center my frame in the view

我被困在 hackingwithswift.com 的 Consolidation IV 挑战中。

现在我正在尝试创建一个刽子手游戏。我想根据答案词的长度放置占位符标签。这些占位符标签将放置在一个框架内,然后将其放置在主视图的中心。

不幸的是,框架的前缘居中放置。在我看来,这不是约束的问题,而是我创建框架的问题。

我当前的密码是

import UIKit

class ViewController: UIViewController {

    var answer: String!

    override func viewDidLoad() {
        super.viewDidLoad()

        // MARK: - declare all the labels here
        let letterView = UIView()
        letterView.translatesAutoresizingMaskIntoConstraints =  false
        view.addSubview(letterView)

        // MARK: - set constraints to all labels, buttons etc.

        NSLayoutConstraint.activate([

            letterView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),
            letterView.centerXAnchor.constraint(equalTo: view.layoutMarginsGuide.centerXAnchor)

        ])

        // MARK: - populate the letterView

        // set the size of the placeholder
        answer = "Atmosphäre"
        let height = 60
        let width = 25
        // var width: Int

        for placeholder in 0..<answer.count {
            // create new label and give it a big font size
            let placeholderLabel = UILabel()
            placeholderLabel.text = "_"
            placeholderLabel.font = UIFont.systemFont(ofSize: 36)

            // calculate frame of this label
            let frame = CGRect(x: placeholder * width, y: height, width: width, height: height)
            placeholderLabel.frame = frame

            // add label to the label view
            letterView.addSubview(placeholderLabel)

        }



    }


}

模拟器屏幕看起来是这样的:

我已经在 Whosebug 上搜索了答案,但没有成功。我想我不知道我到底在找什么。

主要问题是 letterView 没有大小,因为没有对其应用宽度或高度限制。

要修复您的代码,请通过在 for 循环之后添加高度和宽度约束,使 letterView 足够大以包含您添加为子视图的标签:

for placeholder in 0..<answer.count {
   ...         
}

NSLayoutConstraint.activate([
   letterView.widthAnchor.constraint(equalToConstant: CGFloat(width * answer.count)),
   letterView.heightAnchor.constraint(equalToConstant: CGFloat(height))
])

我不确定你是否已经在课程中讲过这个,但是一个更好的方法(需要更少的代码)是使用 UIStackView 作为你的 letterView 代替。

需要考虑的额外事项:

如果您给 letterView 一个背景颜色,您会看到标签实际上在其边界之外对齐:

那是因为您将每个标签的 y 位置设置为 height,而它可能应该为零:

let frame = CGRect(x: placeholder * width, y: 0, width: width, height: height)

更正此问题会将标签置于 letterView:

的范围内