Ios 自动布局不以编程方式';行不通
我想深入了解自动布局,因此我想通过编程来正确理解它。我知道如何通过故事板很好地使用它。下面是我正在做的事情(在Ios 自动布局不以编程方式';行不通,ios,autolayout,programmatically-created,Ios,Autolayout,Programmatically Created,我想深入了解自动布局,因此我想通过编程来正确理解它。我知道如何通过故事板很好地使用它。下面是我正在做的事情(在viewdide:) 这里我用不同的颜色初始化了两个视图 我知道我需要设置属性将自动调整大小GMaskintoConstraints转换为否。所以我做到了 现在我指定了两个视图的高度和宽度。因此,两个视图的x_位置和y_位置都是0。我运行了代码,得到了预期的结果。两个视图在点(0,0)处都具有指定的高度和宽度 问题 现在,当我编写语句“问题语句”以根据viewA的宽度调整viewB的宽度
viewdide:
)
否
。所以我做到了编辑:这里是我所做的一些修改。我已经使用“hasAmbiguousLayout”检查了视图的模糊性,现在它工作正常。现在,如果我想将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);
}
问题是,您已经显式地将A和B的宽度约束分别设置为200和100。因此,当与其他约束组合时,指定一个约束的宽度应为另一个约束宽度的三倍的附加约束是不可满足的 此外,这些约束是不明确的,因为您已经定义了宽度和高度约束,但没有定义两个框架应该在哪里。是的,您已经为这两个视图定义了
框架
,但在应用约束时会忽略该框架。您可能根本不应该定义帧
值,因为这会产生误导和混淆。但是,例如,您应该设置前导约束和顶部约束,或者在VFL中指定这些约束,或者添加centerX
和centerY
约束。您只需要一些约束来指定视图应该放置在哪里,有很多方法可以指定
最后没有看到合理的frame
值的原因是您已经定义了约束,但它们还没有被应用。如果需要,可以在viewdilayoutsubviews
中检查它们
您可能会这样做:
- (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(@"-----");
}
我在我的代码中对我的问题进行了一些修改。你能解释一下吗?@calculater-好的,那么,就像我上面的代码片段一样,从VFL中删除A的宽度定义,然后你可以使用乘数约束。现在,我定义了前导约束和顶部约束(我从您设置帧的尝试中推断),您在编辑中没有使用这些约束,但希望这仍然足够清楚地说明我的观点。不过,我有一个问题……当我在最后的代码中打印viewA和viewB时,为什么它会将帧打印为(0;0 0)?
- (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(@"-----");
}