【问题标题】:Unable to switch between programmable constraints无法在可编程约束之间切换
【发布时间】:2019-08-23 02:37:05
【问题描述】:

我正在尝试在两个可编程视图约束之间切换,具体取决于设备的方向。

为了切换,我在viewWillLayoutSubviews() 中将旧的高度/宽度约束设置为isActive=False,在viewDiDLayoutSubViews() 中将新的约束设置为isActive=True,但是我得到了一个

“不能同时满足约束”

调试中的错误,它阻塞了 newConstraints。

关于在哪里阻止旧约束有什么建议吗?

我的视图的IBOutlet 设置为‘Strong’。在将旧约束更改为isActive=False 后,我也尝试过应用.layoutIfNeeded,但它似乎仍然处于活动状态。

请参阅下面的相关代码。布局最初运行良好,但是在设备旋转后,updateViewLayouts 方法中的新约束被阻止。我相信新的约束是正确的,我只需要在正确的时间禁用旧的约束。

override func viewWillLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if view.orientationHasChanged(&isInPortrait) {
        orientationWillChange()
    }
    if isInPortrait { //Disable Landscape constraints
        imageView1.heightAnchor.constraint(equalTo: frameView.heightAnchor, multiplier: 1.0).isActive = false
        imageView1.widthAnchor.constraint(equalTo: frameView.widthAnchor, multiplier: 0.5).isActive = false
    } else {   //Disable Portrait constraints
        imageView1.heightAnchor.constraint(equalTo: frameView.heightAnchor, multiplier: 0.5).isActive = false
        imageView1.widthAnchor.constraint(equalTo: frameView.widthAnchor, multiplier: 1.0).isActive = false
    }
    imageView1.layoutIfNeeded()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if orientationDidChange {
        updateViewLayouts()
        orientationDidChange = false
    }
}

func updateViewLayouts() {
    imageView1.topAnchor.constraint(equalTo: frameView.topAnchor).isActive = true
    imageView1.leadingAnchor.constraint(equalTo: frameView.leadingAnchor).isActive = true
    if isInPortrait {
        imageView1.heightAnchor.constraint(equalTo: frameView.heightAnchor, multiplier: 0.5).isActive = true
        imageView1.widthAnchor.constraint(equalTo: frameView.widthAnchor, multiplier: 1.0).isActive = true
    } else { //LANDSCAPE
        imageView1.heightAnchor.constraint(equalTo: frameView.heightAnchor, multiplier: 1.0).isActive = true
        imageView1.widthAnchor.constraint(equalTo: frameView.widthAnchor, multiplier: 0.5).isActive = true
    }
}

【问题讨论】:

  • 发布最小代码。
  • 添加了代码。谢谢

标签: swift constraints


【解决方案1】:

这不是它的工作方式

imageView1.heightAnchor.constraint(equalTo: frameView.heightAnchor, multiplier: 1.0).isActive = false

因为每次您调用.constraint(...,它都会创建新的约束并将其返回给您。所以将它设置为 false 是没有意义的,因为它会同时创建和销毁。

要禁用它,您需要引用约束,然后再停用它:

//Persistant variable
var portraitHeightConstraint: NSLayoutConstraint?

// If portrait
portraitHeightConstraint = imageView1.heightAnchor.constraint(equalTo: frameView.heightAnchor, multiplier: 1.0)
portraitHeightConstraint?.isActive = true

// And later if needed
portraitHeightConstraint?.isActive = false

// And same logic for horizontal and other constraints

请注意,我在没有编译器的情况下编写此代码,并且可能存在一些语法错误。不要惊慌。

【讨论】:

  • 谢谢 Mojtaba,这很有效!我在这个问题上被困了一个星期。一旦你指出,解决方案就很明显了。非常感谢:-)
  • 欢迎您。如果这是一个巨大的问题解决者,当你获得足够的声誉时不要忘记投票。 ;)
猜你喜欢
  • 1970-01-01
  • 2016-12-16
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多