简体   繁体   English

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

[英]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: 没有理由手动更新宽度:

  1. Place all the views with equal width in your view with no spacing in between each other 在视图中放置宽度相等的所有视图,彼此之间没有间距
  2. Add an equal width constraint to all of them 为所有这些添加等宽度约束
  3. Add constraints with 0 width for spacing between sides and each other 为边和边之间的间距添加0宽度的约束
  4. Lower the priority of one or more of the equal width constraints just in case the width cannot be divided equally. 降低一个或多个相等宽度约束的优先级,以防宽度不能平均分配。

Then auto layout will handle everything for you. 然后自动布局将为您处理一切。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM