在设备旋转时保持自动布局约束活动状态

我注意到,当我更新我的自动布局约束编程,当我旋转屏幕时,所有的更改被还原。

重现问题:

  • 基本故事板界面与UIView和2个约束:

    1. 宽度相等superview.width(乘数1)有效
    2. 宽度相等superview.width(乘数1/2)禁用
  • 用IBOutlet创build并链接这两个约束

  • 以编程方式禁用第一个约束并启用第二个约束。
  • 旋转设备,第一个约束被激活,第二个约束被禁用。

对我来说似乎是一个错误。

你怎么看 ?

截图:

故事板: 在这里输入图像说明

约束条件1:

在这里输入图像说明

约束条件2:

在这里输入图像说明

大小类

安装是指大小类安装,而不是活动 / 不活动

您必须以编程方式创build另一个约束,并激活/停用约束。 这是因为你不能改变约束的乘数( 我可以改变NSLayoutConstraint的乘数属性吗? ),你也不能修改大小类( activateConstraints:和deactivateConstraints:在IB中创build的约束旋转后不持久 )。

有几种方法可以做到这一点。 在下面的例子中,我使用乘数或1/2创build了x1约束的副本。 然后我在两者之间切换:

@IBOutlet var fullWidthConstraint: NSLayoutConstraint! var halfWidthConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. halfWidthConstraint = NSLayoutConstraint(item: fullWidthConstraint.firstItem, attribute: fullWidthConstraint.firstAttribute, relatedBy: fullWidthConstraint.relation, toItem: fullWidthConstraint.secondItem, attribute: fullWidthConstraint.secondAttribute, multiplier: 0.5, constant: fullWidthConstraint.constant) halfWidthConstraint.priority = fullWidthConstraint.priority } @IBAction func changeConstraintAction(sender: UISwitch) { if sender.on { NSLayoutConstraint.deactivateConstraints([fullWidthConstraint]) NSLayoutConstraint.activateConstraints([halfWidthConstraint]) } else { NSLayoutConstraint.deactivateConstraints([halfWidthConstraint]) NSLayoutConstraint.activateConstraints([fullWidthConstraint]) } } 

testingiOS 9+Xcode 7+

您可以使用通过IB为大小类创build的约束进行必要的切换。 诀窍是将折叠状态保存在一个variables中,并在您的button的事件上更新约束,同时也会在特征集合变化事件上更新约束。

 var collapsed: Bool { didSet { view.setNeedsUpdateConstraints() } } @IBAction func onButtonClick(sender: UISwitch) { view.layoutIfNeeded() collapsed = !collapsed UIView.animate(withDuration: 0.3) { view.layoutIfNeeded() } } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) view.setNeedsUpdateConstraints() } override func updateViewConstraints() { constraint1.isActive = !collapsed constraint2.isActive = collapsed super.updateViewConstraints() }