自动布局约束没有得到尊重

Posted

技术标签:

【中文标题】自动布局约束没有得到尊重【英文标题】:Auto-layout constraints not getting respected 【发布时间】:2016-09-19 22:59:50 【问题描述】:

我正在以编程方式创建约束,以便视图控制器视图具有背景视图和工具栏,工具栏位于底部。我希望背景视图的高度随着工具栏高度的增加而降低。在将背景视图和工具栏作为子视图添加到视图控制器的视图后,我调用(在 viewDidLoad 中)以下以编程方式设置约束的方法。

- (void)configureConstraintsForBackgroundViewAndToolbar 

    [self.backgroundView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.toolbarComponent setTranslatesAutoresizingMaskIntoConstraints:NO];

    UIView *constraintsBackgroundView = self.backgroundView;
    UIView *constraintsToolbar = self.toolbarComponent;

    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(
                                    constraintsBackgroundView, 
                                    constraintsToolbar);
    NSDictionary *metricsDictionary = @
                                        @"toolbarHeight":[NSNumber numberWithFloat:TOOLBAR_HEIGHT]
                                        ;

    [NSLayoutConstraint activateConstraints:
            [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[constraintsBackgroundView]-(0)-|" 
            options:NSLayoutFormatDirectionLeadingToTrailing 
            metrics:metricsDictionary 
            views:viewsDictionary]];

    [NSLayoutConstraint activateConstraints:
            [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[constraintsToolbar]-(0)-|" 
            options:NSLayoutFormatDirectionLeadingToTrailing 
            metrics:metricsDictionary 
            views:viewsDictionary]];

    [NSLayoutConstraint activateConstraints:
            [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(0)-[constraintsBackgroundView]-(0)-[constraintsToolbar(>=toolbarHeight)]-(0)-|" 
            options:NSLayoutFormatDirectionLeadingToTrailing 
            metrics:metricsDictionary 
            views:viewsDictionary]];

直到我尝试使用以下方法(通过嵌入的文本视图)更新工具栏的高度之前,这都可以正常工作。我在这里做错了什么吗?工具栏高度增加,但背景视图的高度没有缩短(我使用 SparkInspector 进行调试)。似乎很简单,这里遗漏了一些明显的东西......

- (void)textViewDidChange:(UITextView *)textView 

    if (textView != self.toolbarTextView) 
        return;
    

    CGFloat currentHeight = self.bounds.size.height;

    CGSize size = [textView sizeThatFits:CGSizeMake(textView.frame.size.width, textView.frame.size.height)];
    CGFloat determinedHeight = fminf(fmaxf(size.height, TOOLBAR_HEIGHT), MAX_TOOLBAR_HEIGHT);

    [self setBounds:CGRectMake(0, 0, self.bounds.size.width, determinedHeight)];    

    [self setNeedsLayout];

另外,如果我查询工具栏和背景视图的约束,我最初设置的彼此之间的约束不会出现?它们确实只为视图控制器的视图显示......这对我来说也不合适......?

非常感谢...

【问题讨论】:

【参考方案1】:

如果您使用约束设置布局,则为视图设置边界或框架以更新布局是没有意义的。而是以您可以通过更改约束的constant 属性来编辑布局的方式添加约束

例如:

使用特定约束设置工具栏的高度并将其存储在属性中

NSLayoutConstraint *toolBarHeightConstraint = [NSLayoutConstraint constraintWithItem:constraintsToolbar
                                                                           attribute:NSLayoutAttributeHeight
                                                                           relatedBy:NSLayoutRelationEqual
                                                                              toItem:self.view
                                                                           attribute:NSLayoutAttributeNotAnAttribute
                                                                          multiplier:1
                                                                            constant:TOOLBAR_HEIGHT];

然后通过更改约束的常量来更改工具栏的高度。 喜欢:

toolBarHeightConstraint.constant = newHeight;

在您的情况下,您还需要将垂直约束更改为:

[NSLayoutConstraint activateConstraints:
            [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(0)-[constraintsBackgroundView]-(0)-[constraintsToolbar]-(0)-|" 
            options:NSLayoutFormatDirectionLeadingToTrailing 
            metrics:metricsDictionary 
            views:viewsDictionary]];

有关更多信息,请查看this 答案。

【讨论】:

谢谢@Ishan Handa ...这很有意义...我可以使用您的建议解决它...再次感谢...

以上是关于自动布局约束没有得到尊重的主要内容,如果未能解决你的问题,请参考以下文章

XCode - 模拟器/设备不尊重自动布局约束

UITableViewCell 子视图不遵守自动布局约束

不使用自动布局的约束?

为按钮提供相等宽度约束时,自动布局设置不正确

当我使用自动布局移动视图时,为啥 XCode 5 没有在情节提要中添加约束

如何使用自动布局“项目格式约束”为 UIViews 设置相等的宽度