2016-08-06 98 views
2

我想进入自动布局的深处,所以我想以编程方式进行编程以便正确理解它。我知道如何通过故事板很好地使用它。现在,这是我我做(在viewDidAppear:AutoLayout以编程方式不起作用

-(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); 

} 
  1. 所以我在这里已经初始化两种不同颜色的看法。

  2. 我知道我需要设置属性。 translatesAutoresizingMaskIntoConstraintsNO,然后应用任何新的约束条件。所以我已经做到了。

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

问题

  • 现在,当我写的语句“问题语句”根据viewA的宽度,其不工作以调节viewB的宽度。

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

  • 任何人都可以解释我的这种行为吗?


    编辑:这里有一些修改,我有made.I使用“hasAmbiguousLayout”,其做工精细now.Now已经检查了双方的意见不确定性应该是什么,下一步,如果我想调整viewB的宽度是viewA的宽度的三倍?

    -(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; 
    
    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)]]; 
    
    
    NSLog(@"%d",viewA.hasAmbiguousLayout); 
    NSLog(@"%d",viewB.hasAmbiguousLayout); 
    
    NSLog(@"%@",viewA); 
    NSLog(@"%@",viewB); 
    
    } 
    

    回答

    2

    问题是,您已经明确地将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(@"-----"); 
    } 
    
    +0

    确定我会尝试纠正它,并在一个瞬间回复。 – Reckoner

    +0

    我已更新我的问题,并在我的代码中进行了一些修改。请给我解释一下吗? – Reckoner

    +0

    @Reckoner - 好的,所以,就像在我上面的代码片段中,从A的VFL中移除宽度定义,然后您可以使用乘数约束。现在,我定义了前导约束和顶端约束(我从您试图设置框架中推断出的),这在编辑时并未使用,但希望这仍然足以说明我的观点。 – Rob

    相关问题