![](/img/trans.png)
[英]Why does a UIStackView with a single view, fill Proportionally, and Layout Margins causes ambiguous constraint error?
[英]Why do embedded UIStackView's, filled Proportionally, with spacing and Layout Margins causes constraint errors and how to fix?
这个问题来自伟大问答的背后:
Stackoverflow:为什么单视图的UIStackView,按比例填充,和Layout Margins会导致模糊约束错误?
我有类似的问题,但在滚动视图中嵌入了堆栈视图。 我已经修改了上述问题的解释代码。 在我的工作代码中,我有一个加载到容器视图中的 parentVC,一个具有嵌入式 scrollView 和 stackViews 的 childVC(外部 stackview 是垂直的,然后它的每个子视图都是一堆水平的 stackviews)。 有一系列选项,包括固定宽度 label、图标和扩展标签。
问题是我得到 UISV 间距约束错误或扩展标签的尾随错误。 我从上述问题中了解到,这与自动布局引擎如何计算比例宽度、间距等的顺序有关,但不知道如何解决。 欢迎大家提出意见。 我附上了我正在使用的代码:
class ParentVC: UIViewController {
override func viewDidLoad() {
let vcContainer = UIView()
view.addSubview(vcContainer)
vcContainer.backgroundColor = .systemYellow
vcContainer.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
vcContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
vcContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -150),
vcContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50),
vcContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50),
])
let vc = ChildVC()
addChild(vc)
vc.didMove(toParent: self)
vcContainer.addSubview(vc.view)
vc.view.frame = vcContainer.bounds
vc.view.heightAnchor.constraint(equalTo: vcContainer.heightAnchor).isActive = true
}
}
class ChildVC: UIViewController {
let outerStackView: UIStackView = {
let v = UIStackView()
v.translatesAutoresizingMaskIntoConstraints = false
v.axis = .vertical
v.spacing = 8
return v
}()
let scrollView: UIScrollView = {
let sv = UIScrollView()
sv.translatesAutoresizingMaskIntoConstraints = false
return sv
}()
override func viewDidLoad() {
super.viewDidLoad()
for _ in 1...7 {
let lbl = UILabel()
lbl.font = UIFont.systemFont(ofSize: 12.0, weight: .light)
lbl.numberOfLines = 0
lbl.textAlignment = .center
outerStackView.addArrangedSubview(lbl)
let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.axis = .horizontal
sv.distribution = .fillProportionally
sv.spacing = 10
outerStackView.addArrangedSubview(sv)
}
view.addSubview(scrollView)
scrollView.addSubview(outerStackView)
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor),
scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor),
outerStackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
outerStackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
outerStackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
outerStackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
outerStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
])
// StackView 1
if let lbl = outerStackView.arrangedSubviews[0] as? UILabel,
let sv = outerStackView.arrangedSubviews[1] as? UIStackView {
let v = ExpandingLabel()
sv.addArrangedSubview(v)
lbl.text = "SV1: One view \n no layoutMargins"
}
// StackView 2
if let lbl = outerStackView.arrangedSubviews[2] as? UILabel,
let sv = outerStackView.arrangedSubviews[3] as? UIStackView {
let v = FixedLabel()
sv.addArrangedSubview(v)
let v2 = ExpandingLabel()
sv.addArrangedSubview(v2)
lbl.text = "SV2: Two views \n no layoutMargins"
}
// comment out this block to see the auto-layout error goes away
// StackView 3
if let lbl = outerStackView.arrangedSubviews[4] as? UILabel,
let sv = outerStackView.arrangedSubviews[5] as? UIStackView {
let v = ExpandingLabel()
sv.addArrangedSubview(v)
sv.isLayoutMarginsRelativeArrangement = true
sv.layoutMargins = .init(top: 0, left: 10, bottom: 0, right: 11)
lbl.text = "SV3: One view\nlayoutMargins left: \(sv.layoutMargins.left), right: \(sv.layoutMargins.right)"
}
// StackView 4
if let lbl = outerStackView.arrangedSubviews[6] as? UILabel,
let sv = outerStackView.arrangedSubviews[7] as? UIStackView {
let v = FixedLabel()
sv.addArrangedSubview(v)
let v2 = ExpandingLabel()
sv.addArrangedSubview(v2)
sv.isLayoutMarginsRelativeArrangement = true
sv.layoutMargins = .init(top: 0, left: 12, bottom: 0, right: 13)
lbl.text = "SV4: Two views\nlayoutMargins\n left: \(sv.layoutMargins.left), right: \(sv.layoutMargins.right)"
}
// StackView 5
if let lbl = outerStackView.arrangedSubviews[8] as? UILabel,
let sv = outerStackView.arrangedSubviews[9] as? UIStackView {
let v = FixedLabel()
sv.addArrangedSubview(v)
let v2 = ExpandingLabel()
sv.addArrangedSubview(v2)
sv.isLayoutMarginsRelativeArrangement = true
sv.layoutMargins = .init(top: 0, left: 101, bottom: 0, right: 0)
lbl.text = "SV5: Two views \nlayoutMargins left: \(sv.layoutMargins.left), right: \(sv.layoutMargins.right)"
}
// StackView 6
if let lbl = outerStackView.arrangedSubviews[10] as? UILabel,
let sv = outerStackView.arrangedSubviews[11] as? UIStackView {
let v = IconView()
sv.addArrangedSubview(v)
let v2 = ExpandingLabel()
v2.numberOfLines = 0
sv.addArrangedSubview(v2)
sv.isLayoutMarginsRelativeArrangement = true
sv.layoutMargins = .init(top: 0, left: 14, bottom: 0, right: 15)
lbl.text = "SV6: Two views\nlayoutMargins left: \(sv.layoutMargins.left), right: \(sv.layoutMargins.right)"
}
// StackView 7
if let lbl = outerStackView.arrangedSubviews[12] as? UILabel,
let sv = outerStackView.arrangedSubviews[13] as? UIStackView {
let v = ExpandingLabel()
sv.addArrangedSubview(v)
sv.isLayoutMarginsRelativeArrangement = true
sv.layoutMargins = .init(top: 0, left: 16, bottom: 0, right: 17)
let v2 = ExpandingLabel()
sv.addArrangedSubview(v2)
lbl.text = "SV7: One view\nlayoutMargins left: \(sv.layoutMargins.left), right: \(sv.layoutMargins.right)"
}
}
}
class IconView: UIImageView {
init() {
super.init(frame: .zero)
self.backgroundColor = UIColor.systemRed
self.tintColor = .white
image = UIImage(systemName: "square.and.arrow.up")?.applyingSymbolConfiguration(UIImage.SymbolConfiguration(textStyle: .body))
contentMode = .center
translatesAutoresizingMaskIntoConstraints = false
adjustsImageSizeForAccessibilityContentSizeCategory = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class FixedLabel : UILabel {
override init(frame: CGRect) {
super.init(frame: frame)
text = "fxd"
backgroundColor = .systemRed
translatesAutoresizingMaskIntoConstraints = false
setContentCompressionResistancePriority(.required, for: .horizontal)
setContentHuggingPriority(.required, for: .horizontal)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class ExpandingLabel: UILabel {
override init(frame: CGRect) {
super.init(frame: frame)
text = "expanding label"
backgroundColor = .systemGreen
numberOfLines = 3
font = UIFont.preferredFont(forTextStyle: .body)
adjustsFontForContentSizeCategory = true
translatesAutoresizingMaskIntoConstraints = false
setContentHuggingPriority(.defaultLow, for: .horizontal)
setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
上述产生的预期结果如下:
日志错误是:
2021-03-16 10:01:22.815997+1100 stackviewsWithProportionalFill[8528:4745644] Sherlock initialised 2021-03-16 10:01:23.051125+1100 stackviewsWithProportionalFill[8528:4745644] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (
"<NSLayoutConstraint:0x600003317e80 'UISV-canvas-connection' UIStackView:0x7feb0270f930.leading == stackviewsWithProportionalFill.FixedLabel:0x7feb02715f80.leading (active)>",
"<NSLayoutConstraint:0x600003317930 'UISV-canvas-connection' H:[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0270b710]-(0)-| (active, names: '|':UIStackView:0x7feb0270f930 )>",
"<NSLayoutConstraint:0x6000033172a0 'UISV-fill-proportionally' stackviewsWithProportionalFill.ExpandingLabel:0x7feb0270b710.width == UIStackView:0x7feb0270f930.width (active)>",
"<NSLayoutConstraint:0x6000033178e0 'UISV-spacing' H:[stackviewsWithProportionalFill.FixedLabel:0x7feb02715f80]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0270b710] (active)>" )
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x6000033178e0 'UISV-spacing' H:[stackviewsWithProportionalFill.FixedLabel:0x7feb02715f80]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0270b710] (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. 2021-03-16 10:01:23.057974+1100 stackviewsWithProportionalFill[8528:4745644] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (
"<NSLayoutConstraint:0x60000332cb40 UIScrollView:0x7feb0381ea00.width == UIView:0x7feb0270aeb0.width (active)>",
"<NSLayoutConstraint:0x60000332d270 UIStackView:0x7feb02709160.width == UIScrollView:0x7feb0381ea00.width (active)>",
"<NSLayoutConstraint:0x600003370fa0 'UISV-alignment' UILabel:0x7feb0270b2a0.leading == UIStackView:0x7feb02711930.leading (active)>",
"<NSLayoutConstraint:0x6000033713b0 'UISV-alignment' UILabel:0x7feb0270b2a0.trailing == UIStackView:0x7feb02711930.trailing (active)>",
"<NSLayoutConstraint:0x600003310eb0 'UISV-canvas-connection' UILayoutGuide:0x6000029208c0'UIViewLayoutMarginsGuide'.leading == stackviewsWithProportionalFill.FixedLabel:0x7feb02717140.leading (active)>",
"<NSLayoutConstraint:0x6000033123f0 'UISV-canvas-connection' UILayoutGuide:0x6000029208c0'UIViewLayoutMarginsGuide'.trailing == stackviewsWithProportionalFill.ExpandingLabel:0x7feb02717530.trailing (active)>",
"<NSLayoutConstraint:0x600003370c80 'UISV-canvas-connection' UIStackView:0x7feb02709160.leading == UILabel:0x7feb0270b2a0.leading (active)>",
"<NSLayoutConstraint:0x600003370cd0 'UISV-canvas-connection' H:[UILabel:0x7feb0270b2a0]-(0)-| (active, names: '|':UIStackView:0x7feb02709160 )>",
"<NSLayoutConstraint:0x600003312530 'UISV-spacing' H:[stackviewsWithProportionalFill.FixedLabel:0x7feb02717140]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb02717530] (active)>",
"<NSLayoutConstraint:0x600003371540 'UIView-Encapsulated-Layout-Width' UIView:0x7feb0270aeb0.width == 0 (active)>",
"<NSLayoutConstraint:0x600003312300 'UIView-leftMargin-guide-constraint' H:|-(101)-[UILayoutGuide:0x6000029208c0'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':UIStackView:0x7feb02711930 )>",
"<NSLayoutConstraint:0x6000033123a0 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000029208c0'UIViewLayoutMarginsGuide']-(0)-|(LTR) (active, names: '|':UIStackView:0x7feb02711930 )>" )
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600003312530 'UISV-spacing' H:[stackviewsWithProportionalFill.FixedLabel:0x7feb02717140]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb02717530] (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. 2021-03-16 10:01:23.065566+1100 stackviewsWithProportionalFill[8528:4745644] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (
"<NSLayoutConstraint:0x60000332cb40 UIScrollView:0x7feb0381ea00.width == UIView:0x7feb0270aeb0.width (active)>",
"<NSLayoutConstraint:0x60000332d270 UIStackView:0x7feb02709160.width == UIScrollView:0x7feb0381ea00.width (active)>",
"<NSLayoutConstraint:0x6000033710e0 'UISV-alignment' UILabel:0x7feb0270b2a0.leading == UIStackView:0x7feb02712730.leading (active)>",
"<NSLayoutConstraint:0x6000033714f0 'UISV-alignment' UILabel:0x7feb0270b2a0.trailing == UIStackView:0x7feb02712730.trailing (active)>",
"<NSLayoutConstraint:0x6000033138e0 'UISV-canvas-connection' UILayoutGuide:0x600002920a80'UIViewLayoutMarginsGuide'.leading == stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260e660.leading (active)>",
"<NSLayoutConstraint:0x600003313930 'UISV-canvas-connection' UILayoutGuide:0x600002920a80'UIViewLayoutMarginsGuide'.trailing == stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260ecd0.trailing (active)>",
"<NSLayoutConstraint:0x600003370c80 'UISV-canvas-connection' UIStackView:0x7feb02709160.leading == UILabel:0x7feb0270b2a0.leading (active)>",
"<NSLayoutConstraint:0x600003370cd0 'UISV-canvas-connection' H:[UILabel:0x7feb0270b2a0]-(0)-| (active, names: '|':UIStackView:0x7feb02709160 )>",
"<NSLayoutConstraint:0x600003370050 'UISV-spacing' H:[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260e660]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260ecd0] (active)>",
"<NSLayoutConstraint:0x600003371540 'UIView-Encapsulated-Layout-Width' UIView:0x7feb0270aeb0.width == 0 (active)>",
"<NSLayoutConstraint:0x6000033137f0 'UIView-leftMargin-guide-constraint' H:|-(16)-[UILayoutGuide:0x600002920a80'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':UIStackView:0x7feb02712730 )>",
"<NSLayoutConstraint:0x600003313890 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600002920a80'UIViewLayoutMarginsGuide']-(17)-|(LTR) (active, names: '|':UIStackView:0x7feb02712730 )>" )
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600003370050 'UISV-spacing' H:[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260e660]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260ecd0] (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. 2021-03-16 10:01:23.066504+1100 stackviewsWithProportionalFill[8528:4745644] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (
"<NSLayoutConstraint:0x60000332cb40 UIScrollView:0x7feb0381ea00.width == UIView:0x7feb0270aeb0.width (active)>",
"<NSLayoutConstraint:0x60000332d270 UIStackView:0x7feb02709160.width == UIScrollView:0x7feb0381ea00.width (active)>",
"<NSLayoutConstraint:0x600003371040 'UISV-alignment' UILabel:0x7feb0270b2a0.leading == UIStackView:0x7feb02712130.leading (active)>",
"<NSLayoutConstraint:0x600003371450 'UISV-alignment' UILabel:0x7feb0270b2a0.trailing == UIStackView:0x7feb02712130.trailing (active)>",
"<NSLayoutConstraint:0x600003312e90 'UISV-canvas-connection' UILayoutGuide:0x600002920b60'UIViewLayoutMarginsGuide'.leading == stackviewsWithProportionalFill.IconView:0x7feb027179a0.leading (active)>",
"<NSLayoutConstraint:0x600003312ee0 'UISV-canvas-connection' UILayoutGuide:0x600002920b60'UIViewLayoutMarginsGuide'.trailing == stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260e1f0.trailing (active)>",
"<NSLayoutConstraint:0x600003370c80 'UISV-canvas-connection' UIStackView:0x7feb02709160.leading == UILabel:0x7feb0270b2a0.leading (active)>",
"<NSLayoutConstraint:0x600003370cd0 'UISV-canvas-connection' H:[UILabel:0x7feb0270b2a0]-(0)-| (active, names: '|':UIStackView:0x7feb02709160 )>",
"<NSLayoutConstraint:0x600003313020 'UISV-spacing' H:[stackviewsWithProportionalFill.IconView:0x7feb027179a0]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260e1f0] (active)>",
"<NSLayoutConstraint:0x600003371540 'UIView-Encapsulated-Layout-Width' UIView:0x7feb0270aeb0.width == 0 (active)>",
"<NSLayoutConstraint:0x600003312da0 'UIView-leftMargin-guide-constraint' H:|-(14)-[UILayoutGuide:0x600002920b60'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':UIStackView:0x7feb02712130 )>",
"<NSLayoutConstraint:0x600003312e40 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600002920b60'UIViewLayoutMarginsGuide']-(15)-|(LTR) (active, names: '|':UIStackView:0x7feb02712130 )>" )
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600003313020 'UISV-spacing' H:[stackviewsWithProportionalFill.IconView:0x7feb027179a0]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb0260e1f0] (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. 2021-03-16 10:01:23.067723+1100 stackviewsWithProportionalFill[8528:4745644] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (
"<NSLayoutConstraint:0x60000332cb40 UIScrollView:0x7feb0381ea00.width == UIView:0x7feb0270aeb0.width (active)>",
"<NSLayoutConstraint:0x60000332d270 UIStackView:0x7feb02709160.width == UIScrollView:0x7feb0381ea00.width (active)>",
"<NSLayoutConstraint:0x600003370f00 'UISV-alignment' UILabel:0x7feb0270b2a0.leading == UIStackView:0x7feb02710b30.leading (active)>",
"<NSLayoutConstraint:0x600003371310 'UISV-alignment' UILabel:0x7feb0270b2a0.trailing == UIStackView:0x7feb02710b30.trailing (active)>",
"<NSLayoutConstraint:0x6000033118b0 'UISV-canvas-connection' UILayoutGuide:0x600002920380'UIViewLayoutMarginsGuide'.leading == stackviewsWithProportionalFill.FixedLabel:0x7feb02716a60.leading (active)>",
"<NSLayoutConstraint:0x600003311900 'UISV-canvas-connection' UILayoutGuide:0x600002920380'UIViewLayoutMarginsGuide'.trailing == stackviewsWithProportionalFill.ExpandingLabel:0x7feb02716cd0.trailing (active)>",
"<NSLayoutConstraint:0x600003370c80 'UISV-canvas-connection' UIStackView:0x7feb02709160.leading == UILabel:0x7feb0270b2a0.leading (active)>",
"<NSLayoutConstraint:0x600003370cd0 'UISV-canvas-connection' H:[UILabel:0x7feb0270b2a0]-(0)-| (active, names: '|':UIStackView:0x7feb02709160 )>",
"<NSLayoutConstraint:0x600003311a40 'UISV-spacing' H:[stackviewsWithProportionalFill.FixedLabel:0x7feb02716a60]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb02716cd0] (active)>",
"<NSLayoutConstraint:0x600003371540 'UIView-Encapsulated-Layout-Width' UIView:0x7feb0270aeb0.width == 0 (active)>",
"<NSLayoutConstraint:0x6000033117c0 'UIView-leftMargin-guide-constraint' H:|-(12)-[UILayoutGuide:0x600002920380'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':UIStackView:0x7feb02710b30 )>",
"<NSLayoutConstraint:0x600003311860 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600002920380'UIViewLayoutMarginsGuide']-(13)-|(LTR) (active, names: '|':UIStackView:0x7feb02710b30 )>" )
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600003311a40 'UISV-spacing' H:[stackviewsWithProportionalFill.FixedLabel:0x7feb02716a60]-(10)-[stackviewsWithProportionalFill.ExpandingLabel:0x7feb02716cd0] (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. 2021-03-16 10:01:23.068649+1100 stackviewsWithProportionalFill[8528:4745644] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (
"<NSLayoutConstraint:0x60000332cb40 UIScrollView:0x7feb0381ea00.width == UIView:0x7feb0270aeb0.width (active)>",
"<NSLayoutConstraint:0x60000332d270 UIStackView:0x7feb02709160.width == UIScrollView:0x7feb0381ea00.width (active)>",
"<NSLayoutConstraint:0x600003370e60 'UISV-alignment' UILabel:0x7feb0270b2a0.leading == UIStackView:0x7feb02710130.leading (active)>",
"<NSLayoutConstraint:0x600003371270 'UISV-alignment' UILabel:0x7feb0270b2a0.trailing == UIStackView:0x7feb02710130.trailing (active)>",
"<NSLayoutConstraint:0x600003316df0 'UISV-canvas-connection' UILayoutGuide:0x600002939880'UIViewLayoutMarginsGuide'.leading == stackviewsWithProportionalFill.ExpandingLabel:0x7feb027167f0.leading (active)>",
"<NSLayoutConstraint:0x600003316da0 'UISV-canvas-connection' UILayoutGuide:0x600002939880'UIViewLayoutMarginsGuide'.trailing == stackviewsWithProportionalFill.ExpandingLabel:0x7feb027167f0.trailing (active)>",
"<NSLayoutConstraint:0x600003370c80 'UISV-canvas-connection' UIStackView:0x7feb02709160.leading == UILabel:0x7feb0270b2a0.leading (active)>",
"<NSLayoutConstraint:0x600003370cd0 'UISV-canvas-connection' H:[UILabel:0x7feb0270b2a0]-(0)-| (active, names: '|':UIStackView:0x7feb02709160 )>",
"<NSLayoutConstraint:0x600003371540 'UIView-Encapsulated-Layout-Width' UIView:0x7feb0270aeb0.width == 0 (active)>",
"<NSLayoutConstraint:0x600003316ee0 'UIView-leftMargin-guide-constraint' H:|-(10)-[UILayoutGuide:0x600002939880'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':UIStackView:0x7feb02710130 )>",
"<NSLayoutConstraint:0x600003316e40 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600002939880'UIViewLayoutMarginsGuide']-(11)-|(LTR) (active, names: '|':UIStackView:0x7feb02710130 )>" )
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600003316da0 'UISV-canvas-connection' UILayoutGuide:0x600002939880'UIViewLayoutMarginsGuide'.trailing == stackviewsWithProportionalFill.ExpandingLabel:0x7feb027167f0.trailing (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. 2021-03-16 10:01:24.091972+1100 stackviewsWithProportionalFill[8528:4745811] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
您无意中提出了我告诉人们*忘记您听说过UIStackView
的.fillProportionally
Distribution 属性的(许多)原因之一...
对于您的水平堆栈视图,您有:
sv.distribution = .fillProportionally
所以你只是告诉自动布局: “按比例拉伸排列的子视图的宽度!”
然后添加 label 作为排列的子视图,并在 label 上设置此属性:
setContentHuggingPriority(.required, for: .horizontal)
所以你只是告诉自动布局: “不要拉伸这个标签的宽度!”
自动布局很难同时拉伸和不拉伸视图:)
除非您确切知道为什么要.fillProportionally
(在这种情况下,这不是您想要的),否则不要使用它。 对于您的布局,您需要默认的.fill
。
因此,如果我们暂时忘记了您将ChildVC
作为子 VC ( grin ) 加载并将ChildVC
设置为“根”视图 controller 并离开sv.distribution =.fillProportionally
,您将收到布局错误。
如果将其更改为sv.distribution =.fill
,则不会出现布局错误。
但是,回到使用那个 VC 作为一个孩子......即使使用.fill
你仍然会得到布局错误。 所以...
将ParentVC
中的“加载孩子”代码更改为:
class ParentVC: UIViewController {
override func viewDidLoad() {
let vcContainer = UIView()
view.addSubview(vcContainer)
vcContainer.backgroundColor = .systemYellow
vcContainer.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
vcContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
vcContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -150),
vcContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50),
vcContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50),
])
let vc = ChildVC()
addChild(vc)
vcContainer.addSubview(vc.view)
vc.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
vc.view.topAnchor.constraint(equalTo: vcContainer.topAnchor),
vc.view.leadingAnchor.constraint(equalTo: vcContainer.leadingAnchor),
vc.view.trailingAnchor.constraint(equalTo: vcContainer.trailingAnchor),
vc.view.bottomAnchor.constraint(equalTo: vcContainer.bottomAnchor),
])
vc.didMove(toParent: self)
}
}
这种方法与sv.distribution =.fill
结合使用,可以消除错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.