了解设置自动约束的位置

Posted

技术标签:

【中文标题】了解设置自动约束的位置【英文标题】:Understanding where auto constraints are being set 【发布时间】:2015-09-14 19:27:02 【问题描述】:

在下面的自动布局挑战 6 中,来自 Ray W,我无法理解代码中的哪个位置,在多次点击后宽度和高度会发生变化。

它在 IB 中设置为 50,在第一次运行时在 tappedImage 方法中,在最后一个 else 条件下,width.constant = 100,但是什么时候重新定义回 50(width.constant = 50 )?!?

并且,在第一次点击后(即该图像的宽度和高度 = 100),接下来点击另一个图像,第一个图像的宽度和高度会回到 50,而第二个图像会增长到 100。最后一个其他条件是否告诉第一张图像调整为 50?

   import UIKit

   class ViewController: UIViewController 

  @IBOutlet weak var rayWidth: NSLayoutConstraint!
  @IBOutlet weak var rayHeight: NSLayoutConstraint!
  @IBOutlet weak var ray: UIImageView!

  @IBOutlet weak var vickiWidth: NSLayoutConstraint!
  @IBOutlet weak var vickiHeight: NSLayoutConstraint!
  @IBOutlet weak var vicki: UIImageView!

  @IBOutlet weak var gregWidth: NSLayoutConstraint!
  @IBOutlet weak var gregHeight: NSLayoutConstraint!
  @IBOutlet weak var greg: UIImageView!

  @IBOutlet weak var micWidth: NSLayoutConstraint!
  @IBOutlet weak var micHeight: NSLayoutConstraint!
  @IBOutlet weak var mic: UIImageView!

  @IBOutlet weak var christineWidth: NSLayoutConstraint!
  @IBOutlet weak var christineHeight: NSLayoutConstraint!
  @IBOutlet weak var christine: UIImageView!

  @IBOutlet weak var name: UILabel!
  @IBOutlet weak var bio: UITextView!

  var heights:[NSLayoutConstraint]!
  var widths:[NSLayoutConstraint]!
  var bios: [String]!
  var names: [String]!


  @IBOutlet weak var emailButton: UIButton!
  var previousHeight: NSLayoutConstraint?
  var previousWidth: NSLayoutConstraint?

  override func viewWillAppear(animated: Bool) 

    bios = ["Ray is an indie software developer currently focusing on iPhone and iPad development, and the administrator of this site. He’s the founder of a small iPhone development studio called Razeware, and is passionate both about making apps and teaching others the techniques to make them.", "Vicki Wenderlich discovered a love of digital art in 2009, and has been making app art and digital illustrations ever since. She is passionate about helping people pursue their dreams, and makes free app art for developers available on her website, http://www.vickiwenderlich.com.", "Greg is an iOS developer and trainer, and has been on the raywenderlich.com editorial team since 2012. He has been nerding out with computers since the Commodore 64 era in the 80s and continues to this day on the web and on iOS. He likes caffeine, codes with two-space tabs, and writes with semicolons.", "Mic Pringle is a developer, editor, podcaster, and video tutorial maker. He's also Razeware's third full-time employee. When not knee-deep in Swift or stood in-front of his green screen, he enjoys spending time with his wife Lucy and their daughter Evie, as-well as attending the football matches of his beloved Fulham FC. You can find Mic on Twitter, GitHub, and Stack Overflow.", "Christine is Ray's administrative assistant. She tries to keep order in the ever expanding world of raywenderlich.com so that Ray and the team can stay focused on making more tutorials, books, and apps!"]
    names = ["Ray Wenderlich", "Vicki Wenderlich", "Greg Heo", "Mic Pringle", "Christine Sweigart"]
    name.text = ""
    emailButton.hidden = true

  

  override func viewDidLoad() 
    super.viewDidLoad()

    var razeware = [ray, vicki, greg, mic, christine]
    heights = [rayHeight, vickiHeight, gregHeight,micHeight,christineHeight]
    widths = [rayWidth, vickiWidth, gregWidth,micWidth,christineWidth]


    for image in razeware 
      var tapGesture = UITapGestureRecognizer(target: self, action: "tappedImage:")
      image.userInteractionEnabled = true
      image.addGestureRecognizer(tapGesture)
    
  

  func tappedImage(sender:UITapGestureRecognizer!) 

    var tag = 0
    // index /  tag who's been tapped
    if let senderTag = sender.view?.tag 
      tag = senderTag
    

    let width = widths[tag]             // get the width  constraint from the array
    let height = heights[tag]

    print(width)

    view.setNeedsUpdateConstraints()

    if previousHeight == height 
      if previousHeight?.constant == 100 
        previousHeight?.constant = 50
        previousWidth?.constant = 50
        print("through here")
        //UIView.animateWithDuration(3.0, animations:  () -> Void in
            self.name.text = ""
            self.bio.text = ""
            self.emailButton.hidden = true
          //  self.view.layoutIfNeeded()
     //   )
       else 
        previousHeight?.constant = 100
        previousWidth?.constant = 100
        print("Going here")
        name.text = names[tag]
        bio.text = bios[tag]
        bio.font = UIFont.systemFontOfSize(15.0)
        bio.textColor = UIColor.whiteColor()
        emailButton.hidden = false
      
     else 
      previousHeight?.constant = 50
      previousWidth?.constant = 50
            UIView.animateWithDuration(5.0, animations:  () -> Void in
            width.constant = 100
            height.constant = 100
            self.name.text = self.names[tag]
            self.bio.text = self.bios[tag]
            self.bio.font = UIFont.systemFontOfSize(15.0)
            self.bio.textColor = UIColor.whiteColor()
            self.emailButton.hidden = false
            self.view.layoutIfNeeded()
        )
    
    print(width)

    previousHeight = height
    previousWidth = width

    print("Previous: \(previousHeight)")
    print("Height: \(height)")
  

  override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  


   

【问题讨论】:

除非在 setNeedsUpdateContraints() 之后定义了另一个值,否则 layoutIfNeeded() 是否会求助于 IB 中定义的约束值?即使在代码中重新定义了约束值? 【参考方案1】:

即使之前在其他地方的代码中重新定义了约束,layoutIfNeeded() 也会恢复为原始 IB 定义的约束值 - 除非在 setNeedsUpdateContraints() 之后再次重新定义约束(以保持其新值)。

这是基于大量的尝试一个更大的错误。或许还有机会得到更好的答案……

【讨论】:

以上是关于了解设置自动约束的位置的主要内容,如果未能解决你的问题,请参考以下文章

如何在情节提要中使用自动布局在不同设备尺寸上设置动态位置的约束

自动布局约束不会设置为 SuperView 的边缘 [重复]

Android-ConstraintLayout(约束布局)-Centering/Circular and with Bias了解一下

IOS自动布局中位置属性约束方程的非恒等式

iOS将autoLayout按钮位置设置为故事板中心的剩余空间

如何为不同的屏幕设置自动大小文本