Swift 无法满足嵌套堆栈视图的约束

Swift 无法满足嵌套堆栈视图的约束,swift,nslayoutconstraint,uistackview,Swift,Nslayoutconstraint,Uistackview,我试着调试控制台中的无法满足约束警告,这会在我从iPhone纵向过渡到iPhone横向时出现,我慢慢变得疯狂。我正在使用带有嵌套堆栈视图的仪表板类型视图。如果“宽度大小”类别为规则,则顶部堆栈将轴更改为.horizontal 视图层次结构: 看法 滚动视图 基本视图 仪表板堆栈视图 顶部堆栈视图 进度视图 统计视图 中间视图 底视图 代码 所有组件在viewDidLoad 当检测到大小类更改时,将操纵约束 调试器输出 当我将iPhone从纵向旋转到横向时会收到此信息

我试着调试控制台中的
无法满足约束
警告,这会在我从iPhone纵向过渡到iPhone横向时出现,我慢慢变得疯狂。我正在使用带有嵌套堆栈视图的仪表板类型视图。如果“宽度大小”类别为规则,则顶部堆栈将轴更改为.horizontal

视图层次结构:
  • 看法
    • 滚动视图
      • 基本视图
        • 仪表板堆栈视图
          • 顶部堆栈视图
            • 进度视图
            • 统计视图
          • 中间视图
          • 底视图

代码
  • 所有组件在
    viewDidLoad
  • 当检测到大小类更改时,将操纵约束
调试器输出 当我将iPhone从纵向旋转到横向时会收到此信息

[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. 
(
    "id: , constant: 0.0",
    "id: , constant: 0.0",
    "id: , constant: 0.0",
    "id: , constant: 0.0",
    "id: progressWidth, constant: 224.0",
    "id: s, constant: 5.0",
    "id: scrollTrail, constant: 5.0",
    "id: UIScrollView-frameLayoutGuide-width, constant: 0.0",
    "id: UISV-canvas-connection, constant: 0.0",
    "id: UISV-canvas-connection, constant: 0.0",
    "id: UISV-canvas-connection, constant: 0.0",
    "id: UIView-Encapsulated-Layout-Width, constant: 896.0",
    "id: UIViewSafeAreaLayoutGuide-left, constant: 44.0",
    "id: UIViewSafeAreaLayoutGuide-right, constant: 44.0"
)

Will attempt to recover by breaking constraint 
id: progressWidth, constant: 224.0

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.
2020-02-26 11:27:51.128311+0000 Haem Data PG Std[9632:2228108] [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. 
(
    "id: progressHeight, constant: 414.0",
    "id: topStackHeight, constant: 185.0",
    "id: UISV-canvas-connection, constant: 0.0",
    "id: UISV-canvas-connection, constant: 0.0"
)

Will attempt to recover by breaking constraint 
id: progressHeight, constant: 414.0

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.
[LayoutConstraints]无法同时满足约束。
可能下面列表中至少有一个约束是您不想要的。
试试这个:
(1) 看看每一个约束,试着找出你不期望的;
(2) 找到添加了不需要的约束的代码,然后修复它。
(
“id:,常数:0.0”,
“id:,常数:0.0”,
“id:,常数:0.0”,
“id:,常数:0.0”,
“id:progressWidth,常数:224.0”,
“id:s,常数:5.0”,
“id:scrollTrail,常量:5.0”,
“id:UIScrollView frameLayoutGuide宽度,常数:0.0”,
“id:UISV画布连接,常量:0.0”,
“id:UISV画布连接,常量:0.0”,
“id:UISV画布连接,常量:0.0”,
“id:UIView封装布局宽度,常数:896.0”,
“id:UIViewSafeArealLayoutGuide左,常数:44.0”,
id:UIViewSafeArealLayoutGuide右侧,常数:44.0
)
将尝试通过打破约束进行恢复
id:progressWidth,常数:224.0
在UIViewAlertForUnsatifiableConstraints处创建一个符号断点,以便在调试器中捕获该断点。
中列出的UIView上UIConstraintBasedLayoutDebugging类别中的方法也可能会有所帮助。
2020-02-26 11:27:51.128311+0000 Haem数据PG Std[9632:2228108][布局约束]无法同时满足约束。
可能下面列表中至少有一个约束是您不想要的。
试试这个:
(1) 看看每一个约束,试着找出你不期望的;
(2) 找到添加了不需要的约束的代码,然后修复它。
(
“id:progressHeight,常数:414.0”,
“id:topStackHeight,常数:185.0”,
“id:UISV画布连接,常量:0.0”,
id:UISV画布连接,常数:0.0
)
将尝试通过打破约束进行恢复
id:progressHeight,常数:414.0
在UIViewAlertForUnsatifiableConstraints处创建一个符号断点,以便在调试器中捕获该断点。
中列出的UIView上UIConstraintBasedLayoutDebugging类别中的方法也可能会有所帮助。

依赖于其他布局操作的约束可能会变得棘手。“自动布局”在尝试满足所有约束时会生成多个“过程”

对于比例约束和可能受堆栈视图影响的约束(它们自己执行布局操作),这一点尤其明显

为了避免警告,通常需要调整约束优先级

而且,在激活/停用约束时,需要注意顺序

我按照您所示布置了对象,对于您的情况,您应该能够通过以下方式解决问题:

  • progressViewHeight
    progressViewWidth
    topStackHeight
    约束的优先级分别更改为
    999
  • 约束更改顺序应为
    • 应首先在视图/标签/etc上设置
      .isActive=false
    • 接下来应该更改视图/标签/etc上的
      .constant
    • 然后在视图/标签等上设置
      .isActive=true
    • 然后更改堆栈视图上的
      .constant
    • 最后更改堆栈视图的
      .axis
并非所有这些都是硬性规定,但从经验来看,这是一个好办法

尝试按上面列出的方式更改约束的优先级,并按如下方式更改
setupDashboardView()
func:

func setupDashboardView() {
    let sizeClass = self.traitCollection

    if sizeClass.isIpad {
        progressViewHeight.isActive = false
        progressViewWidth.constant = (self.dashboardStack.bounds.width*0.25)
        topStackHeight.constant = (self.dashboardStack.bounds.height*0.3)
        topStack.axis = .horizontal
    } else if sizeClass.isIphonePortrait {
        progressViewWidth.isActive = false
        progressViewHeight.isActive = true
        progressViewHeight.constant = self.view.frame.width
        topStackHeight.constant = self.view.frame.width*1.5
        topStack.axis = .vertical
    } else if sizeClass.isIphoneLandscape {
        progressViewHeight.isActive = false
        progressViewWidth.constant = self.view.frame.width*0.25
        progressViewWidth.isActive = true
        topStackHeight.constant = self.view.frame.height*0.5
        topStack.axis = .horizontal
    }
    dashboardStack.spacing = 5
    topStack.spacing = 5

    // not needed
    //self.updateViewConstraints()

    // NEVER call this yourself
    //self.viewDidLayoutSubviews()
}

我相信我们需要查看
TopStackView
ProgressView
的约束,以便了解方向更改时实际激活的内容。
func setupDashboardView() {
    let sizeClass = self.traitCollection

    if sizeClass.isIpad {
        progressViewHeight.isActive = false
        progressViewWidth.constant = (self.dashboardStack.bounds.width*0.25)
        topStackHeight.constant = (self.dashboardStack.bounds.height*0.3)
        topStack.axis = .horizontal
    } else if sizeClass.isIphonePortrait {
        progressViewWidth.isActive = false
        progressViewHeight.isActive = true
        progressViewHeight.constant = self.view.frame.width
        topStackHeight.constant = self.view.frame.width*1.5
        topStack.axis = .vertical
    } else if sizeClass.isIphoneLandscape {
        progressViewHeight.isActive = false
        progressViewWidth.constant = self.view.frame.width*0.25
        progressViewWidth.isActive = true
        topStackHeight.constant = self.view.frame.height*0.5
        topStack.axis = .horizontal
    }
    dashboardStack.spacing = 5
    topStack.spacing = 5

    // not needed
    //self.updateViewConstraints()

    // NEVER call this yourself
    //self.viewDidLayoutSubviews()
}