当我 NSLog myBtn.constraints 时会记录额外的约束

Posted

技术标签:

【中文标题】当我 NSLog myBtn.constraints 时会记录额外的约束【英文标题】:Extra constraints are logged when I NSLog myBtn.constraints 【发布时间】:2016-04-17 07:37:39 【问题描述】:

我在视图中有一个按钮。我在界面生成器中为我的按钮设置了图像。 我在界面生成器中添加到按钮的约束是:

superview 的正确空间 = 10

超级视图的顶部空间 = 10

superview 的底部空间 >= 10

标签的剩余空间 >= 10

一切正常,我的布局没有问题。 但是当我用这段代码记录按钮约束时:

NSLog(@"constraints for btnBack is: %@", self.btnBack.constraints);

控制台日志:

constraints for btnBack is:(

"<NSContentSizeLayoutConstraint:0x7c35c400 H:[UIButton:0x7c3588a0(102)] Hug:250 CompressionResistance:750>"

"<NSContentSizeLayoutConstraint:0x7c35c450 V:[UIButton:0x7c3588a0(92)] Hug:250 CompressionResistance:750>")

我知道上下约束不应该在这里记录,因为它们是超级视图约束而不是按钮约束。 但在这里我没有为按钮添加任何宽度和高度约束(即使在代码中)。

为什么要在控制台中记录限制高度和宽度?

【问题讨论】:

【参考方案1】:

如果视图具有基于其内容的自然宽度,则它将该宽度返回为intrinsicContentSize.width。否则,它将intrinsicContentSize.width 设置为UIViewNoIntrinsicMetric

同样,如果它有一个自然高度,它会将该宽度返回为intrinsicContentSize.height。否则,它将intrinsicContentSize.height 设置为UIViewNoIntrinsicMetric

按钮具有自然大小(宽度和高度),由其标题、字体、图像以及可能的其他细节决定。所以它的intrinsicContentSize.widthintrinsicContentSize.height 都是有效的大小,而不是UIViewNoIntrinsicMetric

intrinsicContentSize.width != UIViewNoIntrinsicMetric 时,自动布局会在视图上安装NSContentSizeLayoutConstraint 类型的特殊约束。同样,当intrinsicContentSize.height != UIViewNoIntrinsicMetric 时,自动布局会在视图上安装一个NSContentSizeLayoutConstraint

有关这些特殊约束的详细信息,请参阅this answer。

【讨论】:

所以你的意思是他们就像真正的约束?我强迫我的标签宽度变大,然后我看到我的按钮缩小了。 (因为我没有为我的按钮添加约束宽度)。如果我将约束宽度添加到我的按钮(在界面生成器中)我的按钮不会缩小。 是的,它们是真正的约束,但默认情况下它们的优先级低于必需 (1000)。添加宽度约束时,默认情况下它的优先级为Required (1000),因此它“获胜”。【参考方案2】:

如果view.translatesAutoresizingMaskIntoConstraintsFALSE,那么 UIKit 可能会将 NSContentSizeLayoutConstraint 添加到视图中。在这种情况下,自动布局使用-sizeThatFits:intrinsicContentSize 来计算视图的大小。

如果您的视图正在从一个超级视图移动到另一个视图,请务必重置 view.translatesAutoresizingMaskIntoConstraints。如果新的超级视图使用自动布局,请将translatesAutoresizingMaskIntoConstraints 设置为FALSE。如果新的superview不使用自动布局,设置为TRUE。如果您未能重置translatesAutoresizingMaskIntoConstraints,那么您可能会看到意外的帧动画。

【讨论】:

以上是关于当我 NSLog myBtn.constraints 时会记录额外的约束的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Swift 中的 print() 不会在目标 C 中将时间戳记录为 NSLog

nsarray 中的 NSLog nsarray

NSLog 可以打印的最大尺寸

带有 CGPoint 数据的 NSLog

Apple Configurator 中未显示 iOS 10 的 NSLog 语句

iPad 上的 Swift Playgrounds,NSLog 在 macOS 上的“Console.app”上不显示任何消息