以编程方式自动布局不起作用

时间:2016-08-06 07:26:16

标签: ios autolayout programmatically-created

我想进入自动布局的深度,所以我想以编程方式进行,以便正确理解它。我知道如何通过故事板很好地使用它。现在我正在做的事情(在{{ 1}})

viewDidAppear:
  1. 所以我在这里用不同颜色初始化了两个视图。

  2. 我知道我需要设置属性。在应用任何新约束之前-(void)scenario2{ PGView *viewA = [[PGView alloc]initWithFrame:CGRectMake(100, 100, 100, 100) andBackgroundColor:[UIColor blackColor]]; [self.view addSubview:viewA]; PGView *viewB = [[PGView alloc]initWithFrame:CGRectMake(200, 300, 100, 100) andBackgroundColor:[UIColor yellowColor]]; [self.view addSubview:viewB]; viewA.translatesAutoresizingMaskIntoConstraints = NO; viewB.translatesAutoresizingMaskIntoConstraints = NO; NSLayoutConstraint *constraint; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[viewB(==100)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(viewB)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[viewB(==100)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(viewB)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[viewA(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(viewA)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[viewA(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(viewA)]]; //problem statement constraint = [NSLayoutConstraint constraintWithItem:viewA attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:viewB attribute:NSLayoutAttributeWidth multiplier: 3.0f constant: 0.0f]; [self.view addConstraint:constraint]; NSLog(@"%@",viewA); NSLog(@"%@",viewB); } translatesAutoresizingMaskIntoConstraints。所以我已经做到了。

  3. 现在我指定两个视图的高度和宽度。因此,两个视图的x_position和y_position都是0.我运行代码,我得到了预期的结果。两个视图在点(0,0)处具有指定的高度和宽度。

  4. 问题

    1. 现在,当我编写语句“问题陈述”以根据viewA的宽度调整viewB的宽度时,它不起作用。

    2. 此外,当我打印视图viewA和viewB时,它会将帧打印为(0,0,0,0)。

    3. 有人能解释一下这种行为吗?

      编辑:这是我做的一些修改。我已经使用'hasAmbiguousLayout'检查了两个视图的模糊性,现在它正常工作。如果我想将viewB的宽度三次调整为该值,那么下一步应该是什么viewA的宽度?

      NO

1 个答案:

答案 0 :(得分:3)

问题是你已经明确地将A和B的宽度约束设置为200和100。因此,当与其他约束结合使用时,指定一个宽度应该是另一个宽度的另外约束是不可满足的。

此外,约束是不明确的,因为您已经定义了宽度和高度约束,但尚未定义两个帧应该在哪里。是的,您已为这两个视图定义了frame,但在应用约束时会忽略它。您可能根本不应该定义frame值,因为它会产生误导和混淆。但是,您应该设置例如前导和顶部约束,或者在VFL中指定它们,或者添加centerXcenterY约束。您只需要一些约束来指示应该放置视图的位置,并且有很多方法可以指定它。

最后你没有看到合理frame值的原因是你已经定义了约束,但它们尚未应用。如果您愿意,可以在viewDidLayoutSubviews中检查它们。

您可以执行以下操作:

- (void)scenario2 {

    PGView *viewA = [PGView new];
    viewA.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:viewA];

    PGView *viewB = [PGView new];
    viewB.backgroundColor = [UIColor blackColor];
    [self.view addSubview:viewB];

    viewA.translatesAutoresizingMaskIntoConstraints = NO;
    viewB.translatesAutoresizingMaskIntoConstraints = NO;

    NSDictionary *views = NSDictionaryOfVariableBindings(viewA, viewB);

    // note, I added `|-100-` to say it's 100 points from the top (and 100 tall)

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[viewB(==100)]" options:0 metrics:nil views:views]];

    // likewise, to say 200 points from the left (and 100 wide)

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-200-[viewB(==100)]" options:0 metrics:nil views:views]];

    // again, 100 from the top (as well as 200 tall)

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[viewA(==200)]" options:0 metrics:nil views:views]];

    // and 100 from the left
    // but I've removed width definition, as we'll use your multiplier constraint below

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[viewA]" options:0 metrics:nil views:views]];

    // now that we've removed the width constraint from the above,
    // this should now work fine

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:viewA attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:viewB attribute:NSLayoutAttributeWidth multiplier: 3.0f constant: 0.0f];
    [self.view addConstraint:constraint];

    // no point in doing this, because constraints haven't yet been applied
    //
    // NSLog(@"%@",viewA);
    // NSLog(@"%@",viewB);
}

// if you want to see where they are, you could do that here:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    for (UIView *view in self.view.subviews) {
        NSLog(@"%@", view);
    }
    NSLog(@"-----");
}