iOS Autolayout - 未在viewDidLayoutSubviews中设置帧大小

时间:2014-10-29 11:32:32

标签: ios iphone xcode autolayout

我使用Autolayout在iOS 8的键盘上工作,将按钮放在视图上。
当我使用约束更改布局时,屏幕上的所有内容都会正确显示,但是当我想知道视图的框架大小时,我的尺寸不合适。

例如:我按一个键,键盘布局会根据我的约束更改并布局所有内容。然后我想知道屏幕上任何按钮的大小 - 我在" viewDidLayoutSubviews"并在控制台中获得该结果:

2014-10-29 12:27:09.088 Keyboard[2193:60674] view did layout subviews
2014-10-29 12:27:09.088 Keyboard[2193:60674] {{inf, inf}, {0, 0}}

按钮具有正确的尺寸和正确的位置,但在尝试获取其框架时,未设置尺寸。

当我的代码在viewDidLayoutSubviews中不起作用时,我必须在哪里放置代码?

我在stackoverflow和其他网站上发现了很多问题,但没有一个问题涉及我的问题。

3 个答案:

答案 0 :(得分:38)

我遇到了一个非常相似的问题(upvoted问题),发现beeef's answer指向了正确的方向。鉴于Apple的文档说不直接调用layoutSubviews(),我改为如下(其中mySubView是self.view的直接子视图):

override func viewDidLayoutSubviews() {
    // self.view's direct subviews are laid out.
    // force my subview to layout its subviews:
    self.mySubView.setNeedsLayout()
    self.mySubView.layoutIfNeeded()

    // here we can get the frame of subviews of mySubView
    // and do useful things with that...
}

仅供参考,在我的情况下,mySubView是一个UIScrollView,我需要获取其子视图的框架,这样我就可以在视图出现之前相应地设置contentOffset。我不确定viewDidLayoutSubviews()是否是最好的地方,但它确保mySubView已经布局。

答案 1 :(得分:9)

是的!我自己解决了这个问题。

我不确定自己是否做对了,但这就是我的想法:

  • viewDidLayoutSubviews在布局更改时名为每次
  • viewDidLayoutSubviews在我的视图的直接子视图进行布局时被调用,但该子视图的子视图在那时没有布局,因此您无法获得它们的大小。

我现在的解决方案是在我的所有视图上手动调用 .layoutSubviews(),其中包含键盘的所有按钮。之后,我得到了我想要的所有按钮的大小。

如果我错了,请纠正我。

答案 2 :(得分:0)

在使用DispatchQueue.asyncAfter()时我总觉得有点脏,但在这种情况下,由于viewDidLayoutSubviews在视图层次结构中的所有AutoLayout调整发生之前被调用,因此感觉有必要。我更喜欢强制使用额外的同步布局。

head