AutoLayout:UIView 中的 UIView 有不正确的框架 [英] AutoLayout: UIView within UIView has incorrect frame

查看:24
本文介绍了AutoLayout:UIView 中的 UIView 有不正确的框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Storyboard 中使用 AutoLayout,一切似乎都很顺利.但是,当我将一个 UIView 放入另一个 UIView 并将我想要的所有约束应用于容器及其子项时,我注意到 viewDidLayoutSubviews: 中的框架不正确.考虑到我的限制,它不是我希望计算的框架,而是一些令人作呕的大框架(尽管在正确的起点).例如,我得到的不是 {{26, 10}, {444, 10}} 框架,而是 {{0, 0}, {320, 568}}em>.

I am working with AutoLayout in Storyboard, and everything seemed to be going fine. However, when I put one UIView within another and apply all the constraints I want to both the container and its children, I notice that the frame is incorrect in viewDidLayoutSubviews:. Rather than being the frame I would expect to be calculated given my constraints, it is some disgustingly large frame (albeit at the correct origin). For example, rather than a frame of {{26, 10}, {444, 10}} I get something like {{0, 0}, {320, 568}}.

奇怪的是,当我将子 UIView 置于另一个 UIView 中时,这种情况发生在子 UIView 中,该 UIView 对其超视图(即视图控制器的视图)应用了一些约束.因为我的印象是我可以期望我的视图根据我在 viewDidLayoutSubviews: 方法中的约束来正确布局,我很困惑为什么会发生这种情况.

Strangely enough, this only happens to the child UIView when I situate it within another UIView that has some constraints applied to it in relation to its superview (which is the view controller's view). As I am under the impression that I can expect my views to be properly laid out according to my constraints in the method viewDidLayoutSubviews:, I am confused as to why this is happening.

我是否做出了任何不正确的假设?如果有人可以帮助我指出正确的方向,我将不胜感激.谢谢!

Am I making any incorrect assumptions? I would appreciate it if someone might help point me in the right direction. Thanks!

注意:如果我在 viewDidAppear: 中进行正确的依赖于框架的设置,这个问题就完全解决了,但这对我来说是一个有点不令人满意的解决方法.

Note: This problem is completely fixed if I do my correct-frame-dependent setup in viewDidAppear:, but this is a somewhat unsatisfying workaround for me.

推荐答案

自动布局对边界的更改不一定在 -viewDidLayoutSubviews 中完成.正如高级自动布局工具箱":

Auto Layout changes to bounds are not necessarily finished in -viewDidLayoutSubviews. As put in "Advance Auto Layout Toolbox":

基于约束的布局是一个迭代过程.布局通行证可以根据之前的布局解决方案对约束进行更改,这再次触发更新另一个布局后的约束通过.

Constraint-based layout is an iterative process. The layout pass can make changes to the constraints based on the previous layout solution, which again triggers updating the constraints following another layout pass.

-viewDidLayoutSubviews 的文档原文有重点的注释:

然而,这个被调用的方法并不表示已经调整了视图子视图的各个布局.

However, this method being called does not indicate that the individual layouts of the view's subviews have been adjusted.

所以子视图中的布局和基于约束的迭代可以继续调整它们的框架,但是如果一个 ViewController 的视图的边界没有改变,它的 -viewWillLayoutSubviews 将不会被调用.

So layout and constraint-based iterations in the subviews could continue to adjust their frames, but if a ViewController's view's bounds don't change, its -viewWillLayoutSubviews won't get called.

既然你说你的设置是依赖于框架的"你有几个选择.

Since you say your setup is "frame-dependent" you have a couple options.

<打击>1.在 -viewWillAppear 中进行设置.比 -viewDidAppear 更好,而且由于您确实需要在所有布局完成后完成所有工作 但在它出现在屏幕上之前,这是该方法存在的合理原因.如果相关,您可以尝试调用 -isMovingToParentViewController确定视图外观改变的原因.

1. Do your setup in -viewWillAppear. Better than -viewDidAppear, and since you really need everything to be done after all the layout if completed but before it appears on screen, this is a legitimate reason why the method is there. If relevant, you could try calling -isMovingToParentViewController as described in Determining Why A View's Appearance Changed.

-viewWillAppear 在视图添加到视图层次结构之前被调用,因此布局可能无法完成.抱歉大家,谢天谢地,有了 Swift UI,我们正在从程序式布局转向声明式布局,这就是原因.

-viewWillAppear is called before the view is added to the view hierarchy and therefor layout may not be completed. Sorry everyone, and thankfully with Swift UI we are moving away from procedural layout to declarative layout, and this is why.

  1. 在您需要的视图上调用 -layoutIfNeeded 以获得正确的值.因为这会完成布局工作,所以成本很高,并且如果在其自己的布局过程中触发,可能会导致重复性工作甚至无限循环.但如果需要将某些值与自动布局同步以便使用它们,它会很有用.
  1. Call -layoutIfNeeded on the views you need to have the correct values where you need them to. Because this does the layout work it's expensive, and it could lead to repetitive work being done or even an infinite loop if triggered during its own layout process. But it's useful if it's needed to sync some values with Auto Layout so they can be used.

如果这不起作用,请告诉我们,这可能与约束本身的性质或其他原因有关.自动布局迭代可能很难同步.祝你好运.

If this doesn't work let us know, it could have to do with the nature of the constraints themselves or something else. The Auto Layout iterations can be tricky to sync with. Good luck.

这篇关于AutoLayout:UIView 中的 UIView 有不正确的框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆