如何将固定大小的 UIView 添加到 UIStackView?

xta*_*xta 3 uikit uiview ios swift

在最新的 Xcode (10.1) 上,我无法使用编程约束将固定大小的 UIView 添加到我的 UIStackView。我认为这应该很简单,但我不明白额外的约束来自哪里(UIKit 必须打破一些来布局视图)。

问题是我期待 100x100 的蓝色 UIView。现实情况是,蓝色 UIView 是 100% 屏幕宽度和 100% 屏幕高度。

我意识到 UIStackView 使用intrinsicContentSize,但是如何使用编程约束正确设置它?

以下是添加了 UIStackView 和 vanilla UIView 的工作游乐场。

注意:如果我将蓝色 UIView 直接添加到 ViewController 的view,则原点 (0,0) 处的大小为 100x100 是正确的。将其添加到堆栈视图会导致约束冲突。

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {

    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white
        self.view = view

        // vertical stack view (full screen)
        let stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        view.addSubview(stackView)

        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: view.topAnchor),
            stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.widthAnchor.constraint(equalTo: view.widthAnchor),
            ])

        // view (100x100)
        let fixedSizeView = UIView()
        fixedSizeView.translatesAutoresizingMaskIntoConstraints = false
        fixedSizeView.backgroundColor = .blue

        stackView.addArrangedSubview(fixedSizeView)

        NSLayoutConstraint.activate([
            fixedSizeView.widthAnchor.constraint(equalToConstant: 100),
            fixedSizeView.heightAnchor.constraint(equalToConstant: 100),
            ])
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

Run Code Online (Sandbox Code Playgroud)

Don*_*Mag 7

a 的主要目的UIStackView排列它的子视图。

因此,您将堆栈视图限制为“填充屏幕”,然后将“蓝色视图”添加为arranged subview...,此时堆栈视图将“接管”蓝色视图的排列。

假设您正在使用堆栈视图,因为您计划添加其他视图,您可以允许子视图确定堆栈视图的框架(即,不限制堆栈视图的宽度和/或高度),或者您需要更改堆栈视图.alignment和/或.distribution属性。

这是您的游乐场页面的修改,以将100 x 100蓝色视图置于超级视图的中心:

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {

    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white
        self.view = view

        // vertical stack view (full screen)
        let stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical

        view.addSubview(stackView)

//      NSLayoutConstraint.activate([
//          stackView.topAnchor.constraint(equalTo: view.topAnchor),
//          stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
//          stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
//          stackView.widthAnchor.constraint(equalTo: view.widthAnchor),
//          ])

        NSLayoutConstraint.activate([
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            ])

        // view (100x100)
        let fixedSizeView = UIView()
        fixedSizeView.translatesAutoresizingMaskIntoConstraints = false
        fixedSizeView.backgroundColor = .blue

        stackView.addArrangedSubview(fixedSizeView)

        NSLayoutConstraint.activate([
            fixedSizeView.widthAnchor.constraint(equalToConstant: 100),
            fixedSizeView.heightAnchor.constraint(equalToConstant: 100),
            ])
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
Run Code Online (Sandbox Code Playgroud)

并且,这里有一个修改,其中两个视图 - 蓝色和红色,每个在100 x 100- 被添加到一个堆栈视图,该视图被限制在超级视图的顶部,.alignment设置为.center

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {

    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white
        self.view = view

        // vertical stack view (full screen)
        let stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.alignment = .center

        view.addSubview(stackView)

        NSLayoutConstraint.activate([
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.topAnchor.constraint(equalTo: view.topAnchor),
            ])

        // view (100x100)
        let fixedSizeBlueView = UIView()
        fixedSizeBlueView.translatesAutoresizingMaskIntoConstraints = false
        fixedSizeBlueView.backgroundColor = .blue

        stackView.addArrangedSubview(fixedSizeBlueView)

        NSLayoutConstraint.activate([
            fixedSizeBlueView.widthAnchor.constraint(equalToConstant: 100),
            fixedSizeBlueView.heightAnchor.constraint(equalToConstant: 100),
            ])

        // view (100x100)
        let fixedSizeRedView = UIView()
        fixedSizeRedView.translatesAutoresizingMaskIntoConstraints = false
        fixedSizeRedView.backgroundColor = .red

        stackView.addArrangedSubview(fixedSizeRedView)

        NSLayoutConstraint.activate([
            fixedSizeRedView.widthAnchor.constraint(equalToConstant: 100),
            fixedSizeRedView.heightAnchor.constraint(equalToConstant: 100),
            ])

    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
Run Code Online (Sandbox Code Playgroud)