Ios 当视图位于视图层次结构的顶部时,以编程方式使用自动布局在屏幕上居中显示UIView

Ios 当视图位于视图层次结构的顶部时,以编程方式使用自动布局在屏幕上居中显示UIView,ios,objective-c,uiview,autolayout,nslayoutconstraint,Ios,Objective C,Uiview,Autolayout,Nslayoutconstraint,我已经实现了一个弹出式UIView,我通过[[[[UIApplication sharedApplication]windows]lastObject]addSubview:popupView]将其添加到最顶部的窗口中,因此它将显示在所有内容的顶部,甚至是键盘上。我需要确保我通过编程创建的这个弹出视图始终保持在屏幕中央。我试图添加自动布局约束,但它不喜欢我试图与最上面的窗口对齐的事实。你能告诉我怎样才能做到这一点吗?多谢各位 这就是我所实现的,它将生成一个(非常详细的)错误,指出“视图层次结构没

我已经实现了一个弹出式UIView,我通过
[[[[UIApplication sharedApplication]windows]lastObject]addSubview:popupView]
将其添加到最顶部的窗口中,因此它将显示在所有内容的顶部,甚至是键盘上。我需要确保我通过编程创建的这个弹出视图始终保持在屏幕中央。我试图添加自动布局约束,但它不喜欢我试图与最上面的窗口对齐的事实。你能告诉我怎样才能做到这一点吗?多谢各位

这就是我所实现的,它将生成一个(非常详细的)错误,指出“视图层次结构没有为约束做好准备…”。。。约束的项必须是该视图“”的后代:

    [popupView setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSLayoutConstraint *cn = nil;
    cn = [NSLayoutConstraint constraintWithItem:popupView
                                      attribute:NSLayoutAttributeCenterX
                                      relatedBy:NSLayoutRelationEqual
                                         toItem:[[[UIApplication sharedApplication] windows] lastObject]
                                      attribute:NSLayoutAttributeCenterX
                                     multiplier:1.0
                                       constant:0];
    [popupView addConstraint:cn];
    cn = [NSLayoutConstraint constraintWithItem:popupView
                                      attribute:NSLayoutAttributeCenterY
                                      relatedBy:NSLayoutRelationEqual
                                         toItem:[[[UIApplication sharedApplication] windows] lastObject]
                                      attribute:NSLayoutAttributeCenterY
                                     multiplier:1.0
                                       constant:0];
    [popupView addConstraint:cn];
    cn = [NSLayoutConstraint constraintWithItem:popupView
                                      attribute:NSLayoutAttributeHeight
                                      relatedBy:NSLayoutRelationEqual
                                         toItem:nil
                                      attribute:NSLayoutAttributeNotAnAttribute
                                     multiplier:1
                                       constant:blockSize.height];
    [popupView addConstraint:cn];
    cn = [NSLayoutConstraint constraintWithItem:popupView
                                      attribute:NSLayoutAttributeWidth
                                      relatedBy:NSLayoutRelationEqual
                                         toItem:nil
                                      attribute:NSLayoutAttributeNotAnAttribute
                                     multiplier:1
                                       constant:blockSize.width];
    [popupView addConstraint: cn];

可以将高度和宽度约束添加到popupView,但由于popupView是窗口的子视图,因此应该将居中约束添加到窗口,而不是popupView(在添加约束之前,需要先将popupView添加为子视图).

不要将视图粘贴到未专门设置用于保存视图的窗口中。你不知道该窗口的真正所有者现在或将来的iOS版本会做什么

创建自己的窗口,并将其
windowLevel
设置为高于键盘的高度。为新窗口提供自己的根视图控制器(这样它将正确处理不同的方向),并将弹出视图居中于该根视图控制器的视图中


您将在的答案中找到许多有用的信息。

@Joey,我的答案旨在解决您的约束问题,但Rob的答案确实是更好的方法——这种方法将为您提供更强健的结构。谢谢,但我想我已经在窗口中添加了居中约束。view1(withItem)是popupView,view2(toItem)是窗口,如果我交换它们也没关系。@Joey,但是你用[popupView addConstraint:cn]向popupView添加了约束;应该是[[[UIApplication sharedApplication]windows]lastObject]addConstraint:cn];层次结构中两个视图之间的约束总是添加到superview中,而不是子视图中。谢谢,尽管这似乎会显著增加复杂性,因为这些“问题”:关键窗口接收所有键盘输入,UIWindow覆盖所有内容,而UIWindow始终是纵向的,不需要旋转,需要添加一个控制器作为窗口的根,并让它处理旋转。我需要用户界面在这个弹出窗口下完全响应,不应该覆盖系统警报(不确定是否会),我需要轮换。你能详细解释一下为什么使用“[[UIApplication sharedApplication]windows]lastObject]”是个坏主意吗?在另一个问题上,这被投了一票我知道你为什么说我不应该那样做。虽然它在模拟器上工作,但在真实设备上的表现却不一样。我实施了你的建议,现在效果很好。感谢您为未来提出了最佳方案。我会接受你的回答,但我也需要rdelmar的回答。太遗憾了,我不能同时接受这两个,希望你能接受a+1.:)