Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
580 views
in Technique[技术] by (71.8m points)

ios - Where to update Autolayout constraints when size changes?

I have several UIViews laid out along the bottom of a containing 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.

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. 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. 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. 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

On all classes that implement the UITraitEnvironment protocol the method traitCollectionDidChange will be called when the trait collection changes, like on rotation. This is the appropiate place to manually update the constraints when using the new Size Classes. You can also animate the transition with the method 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. https://github.com/robb/Cartography


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
...