[英]Where to update Autolayout constraints when size changes?
I have several UIView
s laid out along the bottom of a containing UIView
. 我有几个UIView
布置在一个包含UIView
的底部。 I want these views to always be equal width, and always stretch to collectively fill the width of the containing view (like the emoji keyboard buttons at the bottom). 我希望这些视图始终具有相等的宽度,并始终拉伸以共同填充包含视图的宽度(如底部的表情符号键盘按钮)。 The way I'm approaching this is to set equal widths to one of the views, then just update the width constraint of that view to be superviewWidth / numberOfViews
which will cause all of the other views to update to that same value. 我接近这个的方法是为其中一个视图设置相等的宽度,然后只需将该视图的宽度约束更新为superviewWidth / numberOfViews
,这将导致所有其他视图更新为相同的值。
I am wondering where the code to change the constraint constant needs to go. 我想知道更改约束常量的代码需要去哪里。 It needs to be set before the keyboard appears on screen for the first time and update when rotating the device. 需要在键盘首次出现在屏幕上之前进行设置,并在旋转设备时进行更新。
My first attempt at a solution was to place it in updateViewConstraints
and calculate the width via containerView.frame.size.width
. 我首次尝试解决方案是将其放在updateViewConstraints
并通过containerView.frame.size.width
计算宽度。 But this method is called twice upon load, the first time it calculates the values correctly, but the second time for some reason the containerView
's width is 0.0. 但是这个方法在加载时调用两次,第一次正确计算值,但第二次由于某种原因, containerView
的宽度为0.0。 Another issue is that when rotating, the containerView
's width is not the value that it will be after rotation, it's the current value before rotation. 另一个问题是,旋转时, containerView
的宽度不是旋转后的值,而是旋转前的当前值。 But I don't want to wait until after the rotation completes to update the constraint, because the buttons will be the original size then change which will be jarring to the user. 但是我不想等到旋转完成后更新约束,因为按钮将是原始大小然后更改将对用户产生不利影响。
My question is: where is the most appropriate place to put this code? 我的问题是:放置此代码的最合适位置在哪里? Is there a better way to calculate what the width will be? 有没有更好的方法来计算宽度? I can guarantee it will always be the exact same width as the screen width. 我可以保证它的宽度始终与屏幕宽度完全相同。 And I am using Size Classes in Xcode 6, so willRotateToInterfaceOrientation
and similar methods are deprecated. 我在Xcode 6中使用Size Classes,因此不推荐使用willRotateToInterfaceOrientation
和类似的方法。
On all classes that implement the UITraitEnvironment
protocol the method traitCollectionDidChange
will be called when the trait collection changes, like on rotation. 在实现的所有类UITraitEnvironment
协议的方法traitCollectionDidChange
将被称为在特征集合改变,就像旋转。 This is the appropiate place to manually update the constraints when using the new Size Classes. 在使用新的Size Classes时,这是手动更新约束的合适位置。 You can also animate the transition with the method willTransitionToTraitCollection
您还可以使用方法willTransitionToTraitCollection
为过渡设置动画
Basic example: 基本示例:
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)
}
}
Besides that I want to recommend Cartography, which is a nice library that helps to make auto layout more readable and enjoyable. 除此之外,我想推荐Cartography,这是一个很好的库,有助于使自动布局更具可读性和愉悦性。 https://github.com/robb/Cartography https://github.com/robb/Cartography
There is no reason to update the width manually: 没有理由手动更新宽度:
Then auto layout will handle everything for you. 然后自动布局将为您处理一切。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.