呈现视图控制器后自动布局无效(和许多情况)

时间:2013-07-16 02:10:39

标签: ios modalviewcontroller autolayout ios7

背景

我有一个自定义容器控制器,就像UITabBarController一样,但带有切换动画。我使用自动布局来实现。
因为子控制器之间的切换是动态的,所以当将其视图添加到容器的视图中时,将适当的约束添加到子视图控制器,而不是在IB中预先设置。 (当然,约束被添加到超级视图中)

http://d.pr/i/q6NF容器控制器笔尖设置

PS: 约束的细节
H:| [Child](将约束的常量从左/右更改为动画左/右) H:[儿童(==超级)]
五:| [儿童] |

问题出在哪里:

其中一个子控制器是一个导航控制器,当导航控制器呈现模态视图控制器(使用presentViewController:animated:completion:)并解除它(使用dismissViewControllerAnimated:completion:),出现/解除后,出现问题导航控制器的框架变为(x,y,0,0),看起来自动布局变得无效,可能已删除约束。

http://d.pr/i/VmvL现在/解雇过程

研究

我还没有使用代码来验证这些约束发生了什么,但是使用Spark Inspector,我看到在当前/解除过程中视图显示更改。当我的导航控制器呈现模态视图控制器时,iOS只需交换整个导航控制器的视图到模态视图控制器的视图。当导航控制器的视图返回时,自动布局不再起作用。

可能的解决方案

我提出的解决方案之一是让我的容器控制器提供模态控制器。

或者我只是将容器控制器更改为无自动布局。

事实上,自从我开始使用自动布局以来,这种技术所带来的问题只会占据优势。 除了这个问题,每次界面方向改变时,我的容器控制器内的视图都无法自动布局,看起来子视图在方向改变之前总是使用超视图的框架。我仔细检查了我设置的约束,没有冲突,没有歧义。

我的猜测是我的自定义容器控制器与自动布局系统中的模态视图控制器和界面方向更改不兼容,即使设置了约束。

Xcode环境

Xcode 5 beta,iOS 7SDK,目标iOS6.1 也许SDK环境不对劲?

6 个答案:

答案 0 :(得分:33)

我有similar problem。我在我的根UIView上设置了translatesAutoresizingMaskIntoConstraints = NO;。 它似乎是“最外层的”UIView - 层次结构根目录下的超级视图必须使用默认的translatesAutoresizingMaskIntoConstraints = YES。 一旦我删除了它,一切都按预期工作。

答案 1 :(得分:12)

这可能是由于模棱两可的限制造成的。我建议暂停正在运行的应用程序并输入以下命令进行控制:

po [[UIWindow keyWindow] _autolayoutTrace] 

答案 2 :(得分:6)

如果在for my $element (@{ $xml->{lvl1}[0]{lvl2} }) { 和根视图之间使用自动布局(设置根视图以填充整个UIWindow),这些约束将被另一个视图控制器的全屏显示吹走。

会发生什么,全屏演示的整个层次结构取代UIWindow以下的所有内容 - 您的原始视图被删除(吹走约束)并替换新的视图层次结构。然后,当您的评论被替换时,这些约束将丢失。您需要在UIWindow之类的地方重新创建它们,或者只是确保您的根视图有viewWillAppear:

答案 3 :(得分:4)

我也有同样的问题,当我尝试这个导航控制器时,它工作正常,但没有现在的viewcontroller。使用下面的视图控制器方法以及translatesAutoresizingMaskIntoConstraints来解决此问题。

-(void) viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    self.view.translatesAutoresizingMaskIntoConstraints = NO;
}

现在请告诉我你对它有任何担忧。感谢

答案 4 :(得分:0)

我在使用autolayout进行布局的表视图单元格有类似的问题。从模态视图返回时,单元格的布局无效。我可以在viewDidAppear之后重新布局每个单元格,但它看起来很糟糕。感谢@ palimondo的建议,我开始嗅探translatesAutoresizingMaskIntoConstraints。事实证明,当我不应该将我的表格视图单元格的内容视图设置为translatesAutoresizingMaskIntoConstraints = NO时。

答案 5 :(得分:0)

我遇到了同样的问题,搜索栏容器是错位元素(在UITiewController内部,在UITabBarController中)。我见过的其他解决方案都没有奏效,但我最终通过在viewWillAppear中重新添加布局约束来解决这个问题:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem: self.searchBar.superview
                                                      attribute: NSLayoutAttributeTop
                                                      relatedBy: NSLayoutRelationEqual
                                                         toItem: self.view
                                                      attribute: NSLayoutAttributeTop
                                                     multiplier: 1
                                                       constant: 0]];