我在UIStackView中排列子视图的布局遇到了问题,想知道是否有人可以帮助我理解发生了什么。
所以我有一个带有间距的UIStackView(例如1,但这并不重要)和.fillProportionally分布。我添加了仅具有1x1固有大小(可以是任何东西,只是方形视图)的排列子视图,并且我需要它们在stackView中按比例拉伸。
问题在于,如果我添加没有实际框架,仅具有固有大小的视图,则会得到错误的布局
否则,如果我添加具有相同大小的框架的视图,则一切都按预期工作,
但我真的不想设置视图的框架。
我非常确定这全部都是关于抱紧和压缩阻力优先级的问题,但是无法弄清楚正确答案是什么。
下面是一个Playground示例:
import UIKit
import PlaygroundSupport
class LView: UIView {
// If comment this and leave only intrinsicContentSize - result is wrong
convenience init() {
self.init(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
}
// If comment this and leave only convenience init(), then everything works as expected
public override var intrinsicContentSize: CGSize {
return CGSize(width: 1, height: 1)
}
}
let container = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
container.backgroundColor = UIColor.white
let sv = UIStackView()
container.addSubview(sv)
sv.leftAnchor.constraint(equalTo: container.leftAnchor).isActive = true
sv.rightAnchor.constraint(equalTo: container.rightAnchor).isActive = true
sv.topAnchor.constraint(equalTo: container.topAnchor).isActive = true
sv.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true
sv.translatesAutoresizingMaskIntoConstraints = false
sv.spacing = 1
sv.distribution = .fillProportionally
// Adding arranged subviews to stackView, 24 elements with intrinsic size 1x1
for i in 0..<24 {
let a = LView()
a.backgroundColor = (i%2 == 0 ? UIColor.red : UIColor.blue)
sv.addArrangedSubview(a)
}
sv.layoutIfNeeded()
PlaygroundPage.current.liveView = container
.fillProportionally
更改为.fillEqually
,我得到了你的第二张图片... 这是你想要的吗?(顺便说一句,在你的循环中不需要sv.layoutIfNeeded()
) - DonMag.spacing
不为零时(将其更改为sv.spacing = 0
),似乎.fillProportionally
会产生奇怪的结果,您将得到第二张图片,只是视图之间没有空间。我不知道这是否被认为是“错误”——还是一个“怪癖”。几乎可以认为自动布局正在将比例大小应用于空格——然后使用绝对值渲染它们。 - DonMagwidth
约束应该由UIStackView
自动设置,不是吗?当您将视图添加为arrangedSubview
时,width
约束基于添加的视图的intrisicContentSize
,以及UIStackView
中现有视图的数量和大小进行计算并应用到视图上。为什么我需要再次手动添加width
约束?顺便提一下,如果我检查视图调试,最后一个具有最大宽度的元素,其width
约束被禁用了。在我看来,这相当奇怪。 - Arthur Grishin