2014-10-29 53 views
14

我正在使用Autolayout将按钮放在视图上的iOS 8键盘上工作。
当我使用约束来更改布局时,屏幕上的所有内容都正确显示,但是当我想知道视图的帧大小时,我无法获得正确的大小。iOS Autolayout - 未设置viewDidLayoutSubviews中的帧大小

例如:我按一个键,键盘布局会根据我的约束更改和布置一切。然后我想知道屏幕上的任何按钮的大小 - 我这样做,在“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和其他websited的问题,但没有一个覆盖我的问题。

回答

7

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

我不知道如果我是正确的,但是这就是我认为:

  • viewDidLayoutSubviews得到的每一个时间称为当布局正在发生变化
  • viewDidLayoutSubviews得到的调用时直接子视图我的观点是做了布局,但是那个子视图的子视图在那个时候没有布局,所以你不能得到它们的大小。

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

如果我错了,请纠正我。

+1

为我工作,但我不知道这是否正确。 – JohnHanr 2015-01-19 02:50:12

31

我遇到了一个非常类似的问题(upvoted question),发现beeef's answer指向正确的方向。鉴于苹果的文件说,不叫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已经布置好。

0

当诉诸DispatchQueue.asyncAfter()时,我总觉得有点肮脏,但在这种情况下感觉有保证,因为viewDidLayoutSubviews在视图层次结构中的所有AutoLayout调整发生之前被调用。我更喜欢它强制一个额外的同步布局。

override func viewDidLayoutSubviews() { 
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) { [weak self] in 
     // Updated sub-subview frames can be accessed here 
     // Note - access self weakly here for the unlikely, but possible, case it was deallocated 
    } 
}