【问题标题】:How to add fixed size UIView to UIStackView?如何将固定大小的 UIView 添加到 UIStackView?
【发布时间】:2019-08-01 14:16:32
【问题描述】:

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

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

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

以下是添加了 UIStackView 和原版 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()

【问题讨论】:

  • 根据您的要求使用 StackView 的对齐方式可能对您有用。
  • 我已经尝试过了,但这并没有解决问题。如果您可以提供解决问题的答案(对 Swift Playground 示例的代码修改),我很乐意将其标记为解决方案
  • 内部只有一个UIView,为什么还要使用UIStackView?只需将fixedSizeView 直接添加到视图即可。
  • 见下面的评论/答案。我计划添加几个子视图。作为开发代码的一部分,我首先添加了 1 个视图。在那之后,我正在添加更多的子视图。

标签: ios swift uiview uikit


【解决方案1】:

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

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

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

这是对您的 Playground 页面的修改,将 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()

并且,这是一个修改,其中两个视图 - 蓝色和红色,每个位于 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()

【讨论】:

  • 谢谢,后一个示例(2 个 ui 子视图)是我正在寻找的。因为我想向堆栈视图(标签、按钮、视图等)添加几个不同的子级。问题是向父堆栈视图添加了太多约束并且没有足够的子级。
  • 设置 equalToConstant 解决了我的问题。非常感谢!
猜你喜欢
  • 2016-01-08
  • 2013-09-07
  • 2021-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-09
相关资源
最近更新 更多