【问题标题】:Programmatically retrieve the width and height of a UIView using Auto Layout and NSLayoutConstraints?使用自动布局和 NSLayoutConstraints 以编程方式检索 UIView 的宽度和高度?
【发布时间】:2015-02-05 18:51:08
【问题描述】:

如何获得UIView 的宽度和高度,其大小和位置是使用自动布局和 Apple 的视觉格式语言设置的?

这是代码(view 只是来自UIViewController 的变量):

// Create and add the view
var stageView = UIView()
stageView.setTranslatesAutoresizingMaskIntoConstraints(false) // Since I'm using Auto Layout I turn this off
view.addSubview(stageView)

// Create and add constraints to the containing view
let viewsDictionary = ["stageView":stageView]
let horizontalConstraints: NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-150-[stageView]-150-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
let verticalConstraints: NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:|-100-[stageView]-150-|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: viewsDictionary)
view.addConstraints(horizontalConstraints)
view.addConstraints(verticalConstraints)        
println("stageView.frame=\(stageView.frame)")

得到:

stageView.frame=(0.0,0.0,0.0,0.0)

所以我尝试了:

let fittingSize = stageView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
println("fittingSize=\(fittingSize)")

得到:

fittingSize=(0.0,0.0)

我似乎找不到获取尺寸的方法。我可以使用 Auto Layout 和 Visual Format Language 将子视图添加到 stageView 这个地方就好了,但是我无法获得 stageView 的宽度和高度,我需要进一步定位这些子视图。

有什么想法吗?

【问题讨论】:

  • 尝试添加layoutIfNeeded。您的约束不会立即应用。
  • 你说得对,这行得通。 @Aaron 的答案有更多信息,但我认为有些人可能会喜欢这个答案的简单性。随意添加您的评论作为答案,我会投票赞成这两个答案,因为它们对我都很有用。

标签: ios swift autolayout nslayoutconstraint visual-format-language


【解决方案1】:

你有几个选择:

您可以通过调用setNeedsLayout 强制布局引擎立即调整视图大小,然后调用layoutIfNeeded不推荐,因为它效率低下,并且可能尚未设置布局所需的任何手动框架。您可以在我的answer to this question 上阅读有关此方法的更多信息。

您也可以等到子视图在视图控制器中更新:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    println("stageView.frame = \(stageView.frame)")
}

如果您想了解 UIView 子类(或更常见的是 UITableViewCell 子类,您可以在 layoutSubviews 运行后检查:

override func layoutSubviews() {
    super.layoutSubviews()
    println("self.frame = \(self.frame)")
}

【讨论】:

  • 很好的洞察力。就我而言,我需要在布局所有子视图之前知道 stageView 的大小,因为某些子视图的大小和位置基于 stageView 的大小。感谢您的帮助。
  • @TenaciousJay 你可以将它们表达为你的子视图和它们的父视图之间的约束。这样您就不必担心布局何时发生。
  • @AaronBrager 使用setNeedsLayoutlayoutIfNeeded,我可以指定宽度,以便视图垂直扩展,保持固定宽度吗?
  • @nil 你可以,但为什么不添加一个固定的宽度约束?
【解决方案2】:

你需要检查viewDidLayoutSubviews里面的frame。 此函数在约束计算后运行 它假设看起来像这样

override func viewDidLayoutSubviews()
{
    super.viewDidLayoutSubviews()
    //Print frame here   

} 

【讨论】:

  • 感谢您的回答,但这在我的情况下不起作用,因为我需要在布置其余子视图之前知道 stageView 的大小。
  • 其他答案对您有帮助吗?或者您需要我尝试考虑不同的解决方案?
猜你喜欢
  • 2013-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多