Autolayout以编程方式无法正常工作

时间:2013-07-14 01:48:51

标签: iphone ios autolayout

我必须在自定义的UITableViewCell中以编程方式添加一些约束,我有一个mainView(红色)它将是一个容器(cell.contentView的一个子视图),一个图像和另外两个mainView的子视图。

这是我想要的(蓝色和黄色视图的高度不同,但这是另一个问题):

enter image description here

使用下面的代码(我还没有添加imageView),我有这个:

enter image description here

你可以看到2个子视图具有相同的大小,当我滚动时,有时会显示蓝色视图,有时它会显示为黄色。

代码:

self.mainView = [[UIView alloc]init];
[self.mainView setBackgroundColor:[UIColor redColor]];
[self.mainView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.contentView addSubview:self.mainView];

UIView *blueView = [[UIView alloc]init];
[blueView setTranslatesAutoresizingMaskIntoConstraints:NO];
[blueView setBackgroundColor:[UIColor blueColor]];
[self.mainView addSubview:blueView];

UIView *yelloView = [[UIView alloc]init];
[yelloView setBackgroundColor:[UIColor yellowColor]];
[yelloView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.mainView addSubview:yelloView];
NSDictionary *views = NSDictionaryOfVariableBindings(blueView,yelloView,mainView);

NSMutableArray *results = [NSMutableArray array];
NSString *mainContentView_CVF_H = @"H:|-[blueView]-|";
NSString *mainContentView_CVF_V = @"V:|-[blueView]";
NSArray *mainContentViewConstaints_H = [NSLayoutConstraint constraintsWithVisualFormat:mainContentView_CVF_H options:0 metrics:nil views:views];
NSArray *mainContentViewConstaints_V = [NSLayoutConstraint constraintsWithVisualFormat:mainContentView_CVF_V options:0 metrics:nil views:views];
[results addObjectsFromArray:mainContentViewConstaints_H];
[results addObjectsFromArray:mainContentViewConstaints_V];

NSString *delivelyView_CVF_H = @"H:|-[yelloView]-|";
NSString *delivelyView_CVF_V = @"V:[blueView][yelloView]-|";
NSArray *delivelyViewConstaints_H = [NSLayoutConstraint constraintsWithVisualFormat:delivelyView_CVF_H options:0 metrics:nil views:views];
NSArray *delivelyViewConstaints_V = [NSLayoutConstraint constraintsWithVisualFormat:delivelyView_CVF_V options:0 metrics:nil views:views];
[results addObjectsFromArray:delivelyViewConstaints_H];
[results addObjectsFromArray:delivelyViewConstaints_V];

[self.mainView addConstraints:results];


NSString *mainView_CVF_H = @"H:|-[mainView]-|";
NSString *mainView_CVF_V = @"V:|-[mainView]-|";
results = [NSMutableArray array];
NSArray *mainViewConstaints_H = [NSLayoutConstraint constraintsWithVisualFormat:mainView_CVF_H options:0 metrics:nil views:views];
NSArray *mainViewConstaints_V = [NSLayoutConstraint constraintsWithVisualFormat:mainView_CVF_V options:0 metrics:nil views:views];
[results addObjectsFromArray:mainViewConstaints_H];
[results addObjectsFromArray:mainViewConstaints_V];

[self.contentView addConstraints:results];

我用2个文本替换子视图(蓝色和黄色)而没有任何修改,它们按预期显示。

2个问题:

  • 你可以帮忙:)?

  • 添加约束的顺序很重要?

1 个答案:

答案 0 :(得分:3)

有几点想法:

  1. 不,约束的顺序并不重要。

  2. 另外,您可以将两个垂直约束VLF合并为一个:

    @"V:|-[blueView][yellowView]-|"
    
  3. blueViewyellowView奇怪高度的原因是您的约束条件不明确。您定义蓝色和黄色一起应该跨越共享超级视图的高度,但是您将它留给iOS以准确地确定每个单独的高度。这种歧义可以通过在调试器中运行您的应用程序来确认,在应用程序完成呈现此特定视图集后暂停应用程序,然后在(lldb)提示符下输入:

    po [[UIWindow keyWindow] _autolayoutTrace]
    

    您可能会看到类似这样简化示例的结果:

    $0 = 0x075667b0 
    *<UIWindow:0x718a760>
    |   *<UIView:0x718d090>
    |   |   *<UIView:0x7562490>
    |   |   |   *<UIView:0x75627d0> - AMBIGUOUS LAYOUT
    |   |   |   *<UIView:0x7562880> - AMBIGUOUS LAYOUT
    

    最重要的是,您必须解决这种歧义。如果你想要它们相同的高度(我知道你没有,只是一个例子),你可以这样做:

    @"V:|-[blueView][yellowView(==blueView)]-|"
    

    或者,如果您想说blueView应该是44 px,并且应该调整yellowView的大小来占用其余部分,那么它将是:

    @"V:|-[blueView(44)][yellowView]-|"
    

    如果你想说blueView应该是yellowView高度的两倍,你也可以这样做,但不能用VFL:

    [mainView addConstraint:[NSLayoutConstraint constraintWithItem:blueView
                                                         attribute:NSLayoutAttributeHeight
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:yellowView
                                                         attribute:NSLayoutAttributeHeight
                                                        multiplier:2.0
                                                          constant:0.0]];
    

    但是底线,除非你对iOS做出蓝色和黄色任何旧的随机高度(包括使一个零高度而另一个占据其余空间),你需要一些约束来指示一些规则如何他们每个人都应该很高。

  4. 使用UILabel控件替换蓝色和黄色视图时它起作用的原因是标签具有固有的高度约束,这将使它们成为非零高度,这意味着您将看到两者同时观看。但是使用简单的UIView控件,没有内在的最小高度,因此可以自由地制作任何尺寸的蓝色或黄色,以满足您的约束,包括使一个或另一个为零高度。

    < / LI>

    这里有很多不同的选择。当你告诉我们你不希望蓝色和黄色具有相同的高度时,你没有向我们描述什么会决定它们的相对高度。如果没有关于你想要规定相对蓝色和黄色高度的规则的信息,我们很难帮助你。