尺寸变化时,何处更新Autolayout约束?

我有几个UIView布置在一个包含UIView的底部。 我希望这些视图始终具有相等的宽度,并始终拉伸以共同填充包含视图的宽度(如底部的表情符号键盘按钮)。 我接近这个的方法是为其中一个视图设置相等的宽度,然后只需将该视图的宽度约束更新为superviewWidth / numberOfViews ,这将导致所有其他视图更新为相同的值。

我想知道更改约束常量的代码需要去哪里。 需要在键盘首次出现在屏幕上之前进行设置,并在旋转设备时进行更新。

我首次尝试解决方案是将其放在updateViewConstraints并通过containerView.frame.size.width计算宽度。 但是这个方法在加载时调用两次,第一次正确计算值,但第二次由于某种原因, containerView的宽度为0.0。 另一个问题是,旋转时, containerView的宽度不是旋转后的值,而是旋转前的当前值。 但我不想等到旋转完成后才更新约束,因为按钮将是原始大小然后更改,这将对用户产生不利影响。

我的问题是:放置此代码的最合适的位置在哪里? 有没有更好的方法来计算宽度? 我可以保证它的宽度始终与屏幕宽度完全相同。 我在Xcode 6中使用Size Classes,因此不推荐使用willRotateToInterfaceOrientation和类似的方法。

没有理由手动更新宽度:

  1. 在视图中放置具有相等宽度的所有视图,彼此之间没有间距
  2. 为所有这些添加等宽度约束
  3. 为边和边之间的间距添加0宽度的约束
  4. 降低一个或多个相等宽度约束的优先级,以防宽度不能平均分配。

然后自动布局将为您处理一切。

在实现UITraitEnvironment协议的所有类上,当特征集合发生更改时,将调用UITraitEnvironment方法,如旋转时。 在使用新的大小类时,这是手动更新约束的适当位置。 您还可以使用方法willTransitionToTraitCollection为过渡设置动画

基本示例:

 class ViewController: UIViewController { var constraints = [NSLayoutConstraint]() func updateConstraintsWithTraitCollection(traitCollection: UITraitCollection) { // Remove old constraints view.removeConstraints(constraints) // Create new constraints } override func willTransitionToTraitCollection(newCollection: UITraitCollection!, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator!) { super.willTransitionToTraitCollection(newCollection, withTransitionCoordinator: coordinator) coordinator.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext!) in self.updateConstraintsWithTraitCollection(newCollection) self.view.setNeedsLayout() }, completion: nil) } override func traitCollectionDidChange(previousTraitCollection: UITraitCollection!) { updateConstraintsWithTraitCollection(traitCollection) } } 

除此之外,我想推荐Cartography,这是一个很好的库,有助于使自动布局更具可读性和愉悦性。 https://github.com/robb/Cartography