繁体   English   中英

为什么嵌入的 UIStackView,按比例填充,间距和布局边距会导致约束错误以及如何修复?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM