如何摆脱 UIStackView 添加的不需要的约束?

How to get rid of unwanted constraint added by UIStackView?

我在(垂直)堆栈视图中有一个分段控件,并希望其前缘和后缘与堆栈视图的左右边界有一定距离。

我已经尝试定义宽度约束来执行此操作,并尝试了尾随和前导 space 约束,但在运行时它们会被破坏,因为系统无法 "simultaneously satisfy constraints"。从控制台中可以清楚地看到冲突约束是什么,但我没有添加(见下图)将分段控件绑定到其 UIStackView 容器的左右边缘的约束,因此我不知道如何摆脱他们中的。系统打破了我想保留的约束

我应该清楚,我不一定需要 UISegmentedControl 的宽度约束——尾随和前导 space 约束也适用。为了完全清楚,我需要能够控制分段控件的宽度。

注意下面控制台输出中的 $WIDTH-SEGCTRL。它来自我在 Interface Builder 中的约束中定义的标识符。

2018-11-29 10:43:56.323503-0600 [21479:18697482] [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:0x604000291440 H:[UIStackView:0x7f96373120d0]-(0)-|   (active, names: '|':SectionHeaderView:0x7f9637311e20 )>",
    "<NSLayoutConstraint:0x6040002985b0 H:|-(0)-[UIStackView:0x7f96373120d0]   (active, names: '|':SectionHeaderView:0x7f9637311e20 )>",
    "<NSLayoutConstraint:0x6000004913f0 '$WIDTH-SEGCTRL' UISegmentedControl:0x7f9637312d90.width == 280   (active)>",
    "<NSLayoutConstraint:0x60400029af90 '_UITemporaryLayoutWidth' SectionHeaderView:0x7f9637311e20.width == 320   (active)>",
    "<NSLayoutConstraint:0x604000486720 'UISV-alignment' UIStackView:0x7f96373122d0.leading == UISegmentedControl:0x7f9637312d90.leading   (active)>",
    "<NSLayoutConstraint:0x604000486770 'UISV-alignment' UIStackView:0x7f96373122d0.trailing == UISegmentedControl:0x7f9637312d90.trailing   (active)>",
    "<NSLayoutConstraint:0x604000486680 'UISV-canvas-connection' UIStackView:0x7f96373120d0.leading == UIStackView:0x7f96373122d0.leading   (active)>",
    "<NSLayoutConstraint:0x6040004866d0 'UISV-canvas-connection' H:[UIStackView:0x7f96373122d0]-(0)-|   (active, names: '|':UIStackView:0x7f96373120d0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000004913f0 '$WIDTH-SEGCTRL' UISegmentedControl:0x7f9637312d90.width == 280   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

下面是我添加产生问题的宽度约束前后的照片。可以看到 Xcode 把 280 的宽度限制当成了它无法执行的东西。它将分段控件视为绑定到边缘,但我不明白为什么。

之前:

之后:

要使用堆栈视图布局来做到这一点...

对于垂直堆栈视图,设置 Alignment: Center

对于水平堆栈视图,设置 Width 等于垂直堆栈视图宽度

对于分段控件,设置 Width 等于 Vertical Stack View Width,常数为 -40,这将在每一侧留下 20 磅的填充。根据您的喜好调整常量,或将乘数设置为 0.9 以使分段控件占宽度的 90%。