UIStackView 和另一个 UIStackView 问题中的占位符视图
UIStackView and a placeholder view in another UIStackView problem
如果您在另一个 UIStackView(mainStack)
中有 UIStackView(testStack)
和占位符 UIView(testView)
,则会出现问题。意思是如果testStack
里面没有内容就会崩溃,testView
会把space全部拿走。甚至 testStack
的 content hugging priority
设置为最大值,因此当没有子视图时它应该将其高度折叠为 0。但事实并非如此。如何让它在没有内容的时候崩溃?
PS 如果 testStack
中有项目,一切都按预期进行:testView
获取所有可用的 space,testStack
仅获取 space 以适应其子视图。
class AView: UIView {
lazy var mainStack: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.backgroundColor = .gray
stack.addArrangedSubview(self.testStack)
stack.addArrangedSubview(self.testView)
return stack
}()
let testStack: UIStackView = {
let stack = UIStackView()
stack.backgroundColor = .blue
stack.setContentHuggingPriority(.init(1000), for: .vertical)
return stack
}()
let testView: UIView = {
let view = UIView()
view.backgroundColor = .red
return view
}()
init() {
super.init(frame: .zero)
backgroundColor = .yellow
addSubview(mainStack)
mainStack.translatesAutoresizingMaskIntoConstraints = false
mainStack.topAnchor.constraint(equalTo: topAnchor).isActive = true
mainStack.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
mainStack.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
mainStack.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
当自动布局在 UIStackView
中排列子视图时,它会查看:
- 堆栈视图的
.distribution
属性
- 子视图的高度限制(如果给定)
- 子视图的内部内容大小
由于您没有指定 .distribution
属性,mainStack
使用默认值 .fill
。
A UIStackView
具有 NO 内部内容大小,因此自动布局显示“testStack 的高度为零”
A UIView
具有 NO 内部内容大小,因此自动布局显示“testView 的高度为零”
由于分布是填充,自动布局有效地说:“排列的子视图的高度不明确,所以让我们给最后一个子视图一个零高度,然后填充mainStack 与第一个子视图。
设置 .setContentHuggingPriority
不会有任何效果,因为没有固有的高度可以“拥抱”。
如果您设置 mainStack 的 .distribution = .fillEqually
,您将(如预期)testStack
填充上半部分,testView
填充下半部分。
如果你设置 mainStack 的 .distribution = .fillProportionally
,你会得到相同的结果... testStack
填充上半部分,testView
填充下半部分,因为 .fillProportionally
使用排列的子视图的内部内容大小...在这种情况下,它们都是零,因此“比例”将相等。
如果您设置 mainStack 的 .distribution = .equalSpacing
或 .distribution = .equalCentering
,您将不会看到 testStack
或 testView
... 自动布局会给它们每个零的高度,并用(空)“间距”填充 mainStack
的其余部分。
如果您的目标是 testStack
在它为空时“消失”,您可以:
- 将其隐藏,或者
- 子类化并赋予其固有高度
如果您在另一个 UIStackView(mainStack)
中有 UIStackView(testStack)
和占位符 UIView(testView)
,则会出现问题。意思是如果testStack
里面没有内容就会崩溃,testView
会把space全部拿走。甚至 testStack
的 content hugging priority
设置为最大值,因此当没有子视图时它应该将其高度折叠为 0。但事实并非如此。如何让它在没有内容的时候崩溃?
PS 如果 testStack
中有项目,一切都按预期进行:testView
获取所有可用的 space,testStack
仅获取 space 以适应其子视图。
class AView: UIView {
lazy var mainStack: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.backgroundColor = .gray
stack.addArrangedSubview(self.testStack)
stack.addArrangedSubview(self.testView)
return stack
}()
let testStack: UIStackView = {
let stack = UIStackView()
stack.backgroundColor = .blue
stack.setContentHuggingPriority(.init(1000), for: .vertical)
return stack
}()
let testView: UIView = {
let view = UIView()
view.backgroundColor = .red
return view
}()
init() {
super.init(frame: .zero)
backgroundColor = .yellow
addSubview(mainStack)
mainStack.translatesAutoresizingMaskIntoConstraints = false
mainStack.topAnchor.constraint(equalTo: topAnchor).isActive = true
mainStack.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
mainStack.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
mainStack.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
当自动布局在 UIStackView
中排列子视图时,它会查看:
- 堆栈视图的
.distribution
属性 - 子视图的高度限制(如果给定)
- 子视图的内部内容大小
由于您没有指定 .distribution
属性,mainStack
使用默认值 .fill
。
A UIStackView
具有 NO 内部内容大小,因此自动布局显示“testStack 的高度为零”
A UIView
具有 NO 内部内容大小,因此自动布局显示“testView 的高度为零”
由于分布是填充,自动布局有效地说:“排列的子视图的高度不明确,所以让我们给最后一个子视图一个零高度,然后填充mainStack 与第一个子视图。
设置 .setContentHuggingPriority
不会有任何效果,因为没有固有的高度可以“拥抱”。
如果您设置 mainStack 的 .distribution = .fillEqually
,您将(如预期)testStack
填充上半部分,testView
填充下半部分。
如果你设置 mainStack 的 .distribution = .fillProportionally
,你会得到相同的结果... testStack
填充上半部分,testView
填充下半部分,因为 .fillProportionally
使用排列的子视图的内部内容大小...在这种情况下,它们都是零,因此“比例”将相等。
如果您设置 mainStack 的 .distribution = .equalSpacing
或 .distribution = .equalCentering
,您将不会看到 testStack
或 testView
... 自动布局会给它们每个零的高度,并用(空)“间距”填充 mainStack
的其余部分。
如果您的目标是 testStack
在它为空时“消失”,您可以:
- 将其隐藏,或者
- 子类化并赋予其固有高度