3

我正在练习自动布局并学习动画约束。

我的第一个问题是。如果我动态添加视图,将它们的约束动态添加到父视图似乎很麻烦。有没有什么干净的方法可以实现灵活的布局,可以通过编程方式添加和删除视图?或者这是否意味着我应该为我想要完成的事情想一个更简单的解决方案?

第二个问题。我在代码中创建了两个视图和一些约束。我只是想在加载时调整第一个视图的高度约束,使其变短,而第二个视图将相应地向上移动。

这是一些代码:

first = [[UIView alloc]initWithFrame:CGRectZero];

[first setBackgroundColor:[UIColor blueColor]];

[first setTranslatesAutoresizingMaskIntoConstraints:NO];

[self.view addSubview:first];



UIView *second = [[UIView alloc]initWithFrame:CGRectZero];

[second setBackgroundColor:[UIColor redColor]];

[second setTranslatesAutoresizingMaskIntoConstraints:NO];

[self.view addSubview:second];



NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:first attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:20];

NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:first attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:-20];


top = [NSLayoutConstraint constraintWithItem:first attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:40];

height = [NSLayoutConstraint constraintWithItem:first attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:80];

[self.view addConstraints:@[leading,trailing,top,height]];

[height setConstant:10];

[UIView animateWithDuration:0.5 animations:^{

    [self.view layoutIfNeeded];

}];

好的,所以在底部运行我的动画.. 我的第二个视图已经定位在动画结束时的位置。第一个视图从左上角扩展到右下角。它以对角线进行动画处理,最终高度为 10。

谁能解释这种行为。我注意到如果我分配约束,并使它们在 IBAction(按钮触摸)上动画,那么它将按预期动画。

4

2 回答 2

3

先说第二个问题。你为什么要改变动画viewDidLoad?此时我们知道视图已加载,但它可能没有布局并且绝对不会对用户可见;考虑方法中的约束布局变化viewDidLayoutSubviews

至于第一个问题。大卫 H 的回答是一种方式……而且是一种非常好的方式。为了提供不同的选项,我使用constraintsWithVisualFormat:options:metrics:views:允许我指定视图,然后在所有视图中创建所有必要的约束。它可以是一种更简单的跨多个视图创建约束的方法。取决于您正在做什么,一种方式可能更适合您的需求。

根据评论编辑...

对于必须打破约束的东西,您仍然必须在创​​建新约束之前找到并打破约束。没有办法解决这个问题。您要么引用要打破的约束,要么必须遍历对象上的所有约束才能找到它。ABC 转到 AB 和 C,其中 B 和 C 之间的约束消失了。使用视觉格式输入 X 可能类似于 @"[B]-20-[X]-20-[C]" ,它将为 B 和 X 之间的 20 点间距创建一个约束,第二个约束将是 X 和 C 之间的 20 点间距。请注意,上面的视觉格式仅指定水平定位/间距。您将需要第二行来指定垂直约束。

于 2013-11-01T18:41:06.533 回答
2

我正在做类似的事情,并且可以扩展该技术。对于每个视图(实际上是任何对象),创建一个具有“视图”和“约束”属性的可变字典。视图只是视图,约束是包含两个对象的字典数组,一个“视图”属性和一个“约束”属性。

当您决定添加或拉取视图时,然后找到具有适当视图属性的字典,然后对约束数组进行交互,并将约束(NSLayerConstraint 类型)添加/删除到字典中的姊妹“视图”属性。

通过这种方式,您可以在一种方法中添加和删除所有适当的约束,而不管它们认为它们会影响什么。

显然,您只需要具有仍然在主视图中引用视图的约束。但是,另一种处理方法是将视图的宽度/高度设置为 0,它仍然存在但不可见。或者将其 alpha 更改为 0。

于 2013-11-01T18:18:52.670 回答