为啥我以编程方式创建的视图会忽略其约束?

Posted

技术标签:

【中文标题】为啥我以编程方式创建的视图会忽略其约束?【英文标题】:Why does my programmatically created view ignore its constraints?为什么我以编程方式创建的视图会忽略其约束? 【发布时间】:2014-02-10 20:56:19 【问题描述】:

我有一个以编程方式创建子视图并向其添加一些约束的视图。由于某种原因,这些约束被完全忽略了。没有错误被抛出。约束根本不生效。子视图与其父视图具有相同的框架。我希望它是 400x400 并以它的超级视图为中心。我在这里做错了什么?这是我在超级视图中的 initWithFrame:

- (id) initWithFrame:(CGRect)frame

    if (self = [super initWithFrame:frame])
    
        instructionsView = [[UIView alloc] initWithFrame:frame];
        [self addSubview:instructionsView];
        [self bringSubviewToFront:instructionsView];

        [self addConstraint:[NSLayoutConstraint constraintWithItem:instructionsView
                                                         attribute:NSLayoutAttributeCenterX
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self
                                                         attribute:NSLayoutAttributeCenterX
                                                        multiplier:1.
                                                          constant:0]];

        [self addConstraint:[NSLayoutConstraint constraintWithItem:instructionsView
                                                         attribute:NSLayoutAttributeCenterY
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self
                                                         attribute:NSLayoutAttributeCenterY
                                                        multiplier:1.
                                                          constant:0]];

        [instructionsView addConstraint:[NSLayoutConstraint constraintWithItem:instructionsView
                                                                     attribute:NSLayoutAttributeWidth
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:nil
                                                                     attribute:NSLayoutAttributeNotAnAttribute
                                                                    multiplier:1.
                                                                      constant:400]];

        [instructionsView addConstraint:[NSLayoutConstraint constraintWithItem:instructionsView
                                                                     attribute:NSLayoutAttributeHeight
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:nil
                                                                     attribute:NSLayoutAttributeNotAnAttribute
                                                                    multiplier:1.
                                                                      constant:400]];
    
    return self;

我尝试过改变

instructionsView = [[UIView alloc] initWithFrame:frame];

instructionsView = [[UIView alloc] initWithFrame:CGRectZero];

没有成功。

【问题讨论】:

【参考方案1】:

您需要告诉视图不要使用基于掩码的自动调整大小布局,而是使用自动布局

instructionsView.translatesAutoresizingMaskIntoConstraints = NO;

见documentation here

另外,视图应该在没有框架的情况下创建,这主要是一种样式,但是像这样创建你的视图:

instructionsView = [[UIView alloc] init];

【讨论】:

【参考方案2】:

歧义会导致令人惊讶的结果,而不会引发任何异常。要调试歧义约束,请在调试器中暂停并在 lldb 命令行中键入:

po [[UIWindow keyWindow] _autolayoutTrace]

此外,您可以(并且应该)在 UIView 上添加一个方法(通过一个类别),让您在层次结构中递归调用 hasAmbiguousLayout

最后,您可以(并且应该)在 UIView 上添加一个方法(通过一个类别),让您在层次结构中递归调用 constraintsAffectingLayoutForOrientation:

通过这种方式,您可以追踪真正发生的事情。

【讨论】:

以上是关于为啥我以编程方式创建的视图会忽略其约束?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式创建的 UIView 的框架为 0

为啥我的 UITableView 单元格在滚动时重叠?

为啥我以编程方式创建的按钮的样式不同?

当我以编程方式更改约束时 Xcode 给出错误

堆栈视图内的布局约束(以编程方式快速)

在另一个以编程方式创建的视图下方布局视图