iOS - 在viewdidload中以一种意想不到的方式限制动画?

时间:2013-11-01 17:49:10

标签: ios cocoa-touch uiview autolayout constraints

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

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

第二个问题。我创建了两个视图,并在代码中创建了一些约束。我只是试图在加载的第一个视图上调整高度约束,以便它变短,第二个视图将相应地向上移动。

这里有一些代码:

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(按钮触摸)上制作动画,那么它将按预期动画。

2 个答案:

答案 0 :(得分:3)

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

至于第一个问题。 David H的回答是单向的......而且是一种完美的方式。为了给出不同的选项,我使用constraintsWithVisualFormat:options:metrics:views:允许我指定视图,然后在所有视图中创建所有必要的约束。在多个视图中创建约束可能是一种更简单的方法。根据您正在做的事情,一种方式可能更适合您的需求。

根据评论

编辑

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

答案 1 :(得分:2)

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

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

通过这种方式,您可以在一种方法中添加和删除所有适当的约束,无论它们看到它们的影响如何。

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

相关问题