以编程方式将自动布局约束添加到恒定宽度和高度的子视图

Posted

技术标签:

【中文标题】以编程方式将自动布局约束添加到恒定宽度和高度的子视图【英文标题】:Adding Auto Layout constraints programmatically to a subview of constant width and height 【发布时间】:2013-10-15 10:04:22 【问题描述】:

我有一个大小为 20x40 的 UIView,它已被添加为 ViewController 的子视图。较小的 UIView 可以在屏幕上拖动,根据拖动到的位置,UIView 将重置“X”坐标以贴在屏幕边缘。

但是,我想使用/学习“自动布局”向此子视图添加约束,以在横向和纵向模式下保持相同的宽度和高度。

到目前为止的代码:

self.anotherView = [[UIView alloc] initWithFrame: CGRectMake (0.0,(self.view.frame.size.height/2)-45.0f-self.navigationController.navigationBar.frame.size.height,20.0,45.0f)];
    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(dragging:)];
    [self.anotherView addGestureRecognizer:panRecognizer];
    [self.anotherView setBackgroundColor: [UIColor blueColor]];
    self.anotherView.translatesAutoresizingMaskIntoConstraints = NO;

    [self.view addSubview: self.anotherView];
    [self.view bringSubviewToFront:self.anotherView];

    NSDictionary *views = @@"subview" : self.anotherView, @"superview" : self.view;


    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview(==20)]|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:views]];


    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[subview(==40)]" options:NSLayoutFormatAlignAllBaseline metrics:nil views:views]];


    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self.anotherView attribute:NSLayoutAttributeBaseline relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:self.view.bounds.size.height];
        [self.view addConstraint:constraint];

但是,上面的代码给了我以下错误:

Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x8b4ef80 H:|-(0)-[UIView:0x8b4eab0]   (Names: '|':UIView:0x8b4cc80 )>",
    "<NSLayoutConstraint:0x8b4f020 H:[UIView:0x8b4eab0(20)]>",
    "<NSLayoutConstraint:0x8b4f0f0 H:[UIView:0x8b4eab0]-(0)-|   (Names: '|':UIView:0x8b4cc80 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x8aa1d30 h=--& v=--& H:[UIView:0x8b4cc80(320)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x8b4f0f0 H:[UIView:0x8b4eab0]-(0)-|   (Names: '|':UIView:0x8b4cc80 )>

Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

我到底做错了什么?另外,我正在使用 Storyboard,并且只有这个视图作为子视图添加到 ViewController。请在下方查看当前 UI 的屏幕截图。

【问题讨论】:

【参考方案1】:
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview(==20)]|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:views]];

这就是说您希望子视图为 20 点宽,并且还固定在父视图的左右边缘,这是一个表格单元格的内容视图,因此宽度为 320 点。

如果您只想限制视图的宽度,请不要在 VFL 字符串中包含超级视图指示符 (|),就像您对垂直约束所做的那样,或者使用 autolayout helper category 和一些很好的限制大小的方法。

要拥有可变位置,您需要一个单独的约束将视图的左边缘固定到其父视图,并且此约束的constant 将随着用户拖动而更新。

【讨论】:

感谢您为我指明了正确的方向。虽然我喜欢自动布局助手类别,但在我了解有关自动布局的一两件事之前,我会限制使用它。我得到了初始布局(感谢您的回答)现在需要处理拖动部分。

以上是关于以编程方式将自动布局约束添加到恒定宽度和高度的子视图的主要内容,如果未能解决你的问题,请参考以下文章

如何在ios swift中以编程方式创建自动布局等宽度约束?

如何使用自动布局对子视图进行编程以占用其父视图宽度的 50% 但保持恒定高度?

UICollectionViewCell 以编程方式自动布局

添加 UIView 并使用自动布局重新计算约束

以编程方式使用自动布局将子视图添加到 UICollectionView 不起作用

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