[英]UIStackView's subviews have intrinsic size, yet still ignore content hugging priorities
I'm trying to programmatically create a stack view with a fill distribution that allows me to choose which subview stretches to fill the extra space, but so far I can't seem to control which view is expanding.我正在尝试以编程方式创建一个带有填充分布的堆栈视图,它允许我选择哪些子视图拉伸以填充额外的空间,但到目前为止我似乎无法控制哪个视图正在扩展。
class ShelfVC: UIViewController {
let shelfContentView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(shelfContentView)
shelfContentView.translatesAutoresizingMaskIntoConstraints = false
shelfContentView.layoutEqualTo(view: view)
shelfContentView.spacing = 16
shelfContentView.isLayoutMarginsRelativeArrangement = true
let shelfMargin = CGFloat(16)
shelfContentView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: shelfMargin, leading: shelfMargin, bottom: shelfMargin, trailing: shelfMargin)
createTestBlocks()
}
func createTestBlocks() {
let view1 = UIView()
shelfContentView.addArrangedSubview(view1)
view1.widthAnchor.constraint(equalToConstant: 100).isActive = true
view1.backgroundColor = .systemRed
view1.setContentHuggingPriority(.defaultHigh, for: .horizontal)
let view2 = UIView()
shelfContentView.addArrangedSubview(view2)
view2.widthAnchor.constraint(equalToConstant: 100).isActive = true
view2.backgroundColor = .systemPurple
view2.setContentHuggingPriority(.defaultLow, for: .horizontal)
let view3 = UIView( )
shelfContentView.addArrangedSubview(view3)
view3.widthAnchor.constraint(equalToConstant: 100).isActive = true
view3.backgroundColor = .systemBlue
view3.setContentHuggingPriority(.defaultHigh, for: .horizontal)
}
}
I'm expecting to see this:我期待看到这个:
But instead, I see this:但相反,我看到了这个:
Why does the blue view stretch when it's hugging priority is higher than the purple view?当拥抱优先级高于紫色视图时,为什么蓝色视图会拉伸?
UIStackView
shrinks and expands using .fill
based on the content compression priority if the arranged subviews don't fill the stack view.如果排列的子视图未填充堆栈视图,则.fill
根据内容压缩优先级使用UIStackView
收缩和扩展。 Thus, try changing setContentHuggingPriority
to setContentCompressionResistancePriority
.因此,尝试将setContentHuggingPriority
更改为setContentCompressionResistancePriority
。
See https://developer.apple.com/documentation/uikit/uistackview/distribution/fill for more information on the UIStackView.Distribution.fill
property.有关UIStackView.Distribution.fill
属性的更多信息,请参阅https://developer.apple.com/documentation/uikit/uistackview/distribution/fill 。
Content Hugging Priority is not the same as Constraint Priority, and Constraints do not define Intrinsic Content Size.内容拥抱优先级与约束优先级不同,约束不定义内在内容大小。
Content Hugging (and Content Compression Resistance) Priority is based on Intrinsic content size.内容拥抱(和内容压缩阻力)优先级基于内在内容大小。
You've given each view a Width constraint, and your stack view is using that to begin the arrangement.您已为每个视图提供了一个宽度约束,并且您的堆栈视图正在使用它来开始排列。 It then breaks one of the constraints because it cannot satisfy all of them.然后它打破了其中一个约束,因为它不能满足所有这些约束。
You have two options:你有两个选择:
Here is the first example:这是第一个例子:
class ConstraintHuggingShelfVC: UIViewController {
let shelfContentView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(shelfContentView)
shelfContentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
shelfContentView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0),
shelfContentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0),
shelfContentView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0),
shelfContentView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0),
])
//shelfContentView.layoutEqualTo(view: view)
shelfContentView.spacing = 16
shelfContentView.isLayoutMarginsRelativeArrangement = true
let shelfMargin = CGFloat(16)
shelfContentView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: shelfMargin, leading: shelfMargin, bottom: shelfMargin, trailing: shelfMargin)
createTestBlocks()
}
func createTestBlocks() {
let view1 = UIView()
shelfContentView.addArrangedSubview(view1)
view1.backgroundColor = .systemRed
let wc1 = view1.widthAnchor.constraint(equalToConstant: 100)
wc1.isActive = true
wc1.priority = .defaultHigh
let view2 = UIView()
shelfContentView.addArrangedSubview(view2)
view2.backgroundColor = .systemPurple
let wc2 = view2.widthAnchor.constraint(equalToConstant: 100)
wc2.isActive = true
wc2.priority = .defaultLow
let view3 = UIView( )
shelfContentView.addArrangedSubview(view3)
view3.backgroundColor = .systemBlue
let wc3 = view3.widthAnchor.constraint(equalToConstant: 100)
wc3.isActive = true
wc3.priority = .defaultHigh
}
}
and here's the second example:这是第二个例子:
class IntrinsicView: UIView {
var myIntrinsicSize: CGSize = .zero
override var intrinsicContentSize: CGSize {
return myIntrinsicSize
}
}
class IntrisicSizeShelfVC: UIViewController {
let shelfContentView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(shelfContentView)
shelfContentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
shelfContentView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0),
shelfContentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0),
shelfContentView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0),
shelfContentView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0),
])
// shelfContentView.layoutEqualTo(view: view)
shelfContentView.spacing = 16
shelfContentView.isLayoutMarginsRelativeArrangement = true
let shelfMargin = CGFloat(16)
shelfContentView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: shelfMargin, leading: shelfMargin, bottom: shelfMargin, trailing: shelfMargin)
createTestBlocks()
}
func createTestBlocks() {
let view1 = IntrinsicView()
shelfContentView.addArrangedSubview(view1)
view1.backgroundColor = .systemRed
view1.myIntrinsicSize = CGSize(width: 100, height: 0)
view1.setContentHuggingPriority(.defaultHigh, for: .horizontal)
let view2 = IntrinsicView()
shelfContentView.addArrangedSubview(view2)
view2.backgroundColor = .systemPurple
view2.myIntrinsicSize = CGSize(width: 100, height: 0)
view2.setContentHuggingPriority(.defaultLow, for: .horizontal)
let view3 = IntrinsicView( )
shelfContentView.addArrangedSubview(view3)
view3.backgroundColor = .systemBlue
view3.myIntrinsicSize = CGSize(width: 100, height: 0)
view3.setContentHuggingPriority(.defaultHigh, for: .horizontal)
}
}
Both produce the identical layout:两者都产生相同的布局:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.