animation和自动布局

我有一系列的视图堆叠这种方式

________________ | | | View 1 | |________________| | | | View 2 | |________________| | | | View 3 | |________________| 

这些视图可以展开和折叠,因此如果展开视图1,则视图2的顶部位于视图1的底部,而与视图2相关的视图3也相同。

  ________________ | | | View 1 | | | | | | | |________________| | | | View 2 | |________________| | | | View 3 | |________________| ________________ | | | View 1 | |________________| | | | View 2 | | | | | | | |________________| | | | View 3 | |________________| 

我不能通过IB添加这些视图,因为这个布局是dinamycally创build的,所以我必须通过代码和约束来添加视图。

我正在这样做

 UIView *previousView = nil; for (UIView *view in views) { if (previousView) { NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousView][view]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(previousView, view)]; [superview addConstraints:constraints]; } } 

当我点击一个视图来扩展它时,我收到一个错误

 Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x76407b0 h=&-& v=--& V:[MyView:0x764c0f0(44)]>", "<NSAutoresizingMaskLayoutConstraint:0x763e370 h=&-& v=--& V:[MyView:0x7646490(44)]>", "<NSLayoutConstraint:0x76440d0 V:[MyView:0x764c0f0]-(0)-[MyView:0x7648eb0]>", "<NSLayoutConstraint:0x7643920 V:[MyView:0x7648eb0]-(0)-[MyView:0x7646490]>", "<NSAutoresizingMaskLayoutConstraint:0x76407f0 h=&-& v=--& MyView:0x764c0f0.midY == + 22>", "<NSAutoresizingMaskLayoutConstraint:0x76d9ea0 h=&-& v=--& MyView:0x7648eb0.midY == + 91.5>", "<NSAutoresizingMaskLayoutConstraint:0x763e3b0 h=&-& v=--& MyView:0x7646490.midY == + 110>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7643920 V:[MyView:0x7648eb0]-(0)-[MyView:0x7646490]> 

显然我做错了。 我是否必须将setTranslatesAutoresizingMaskIntoConstraints设置为NO ,并将自己的约束添加到定位中? 或者问题是我在这个循环上添加的约束?

你怎么改变视图的大小? 你有一个约束,修复你的两个视图之间的垂直空间为0.你得到的错误是否显示了其他约束(可能是你没有明确添加的约束)? 我怀疑在视图2和/或视图3上可能存在另一个约束,不允许它们向下移动以满足V-[View 1]-(0)-[View 2]约束。

如果没有其他限制,只需要改变想要展开或者折叠的视图的高度即可。

正如苹果文档中提到的,如果你自己设置了所有的约束,你应该调用setTranslatesAutoresizingMaskIntoConstraints:NO否则你的显式约束将会与隐含添加的Autoresizing Mask约束相冲突,这看起来就像在这种情况下发生的情况。

编辑:看到你的编辑上面列出所有的约束,它证实了我在说什么。 通过转换自动resize的掩码添加的约束与您的自动布局约束相冲突。 他们明确地将每个视图的中心Y位置与超视图相关联。 尝试setTranslatesAutoresizingMaskIntoConstraints:NO并根据需要设置您需要的任何其他约束。

使用自动布局时,如果要重新布置视图,则应该更改约束而不是视图的框架。
你可以参考这个例子:

 #define VIEW_COLLAPSED_HEIGHT 50 #define VIEW_EXPANDED_HEIGHT 100 @interface ViewController () @property (nonatomic, strong) NSLayoutConstraint *constraintHeight1; @property (nonatomic, strong) NSLayoutConstraint *constraintHeight2; @property (nonatomic, strong) NSLayoutConstraint *constraintHeight3; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //Create 3 views UIView *v1 = [[UIView alloc] init]; v1.translatesAutoresizingMaskIntoConstraints = NO; v1.backgroundColor = [UIColor yellowColor]; [self.view addSubview:v1]; UIView *v2 = [[UIView alloc] init]; v2.translatesAutoresizingMaskIntoConstraints = NO; v2.backgroundColor = [UIColor blueColor]; [self.view addSubview:v2]; UIView *v3 = [[UIView alloc] init]; v3.translatesAutoresizingMaskIntoConstraints = NO; v3.backgroundColor = [UIColor greenColor]; [self.view addSubview:v3]; //Add constraints: NSDictionary *variableBindings = NSDictionaryOfVariableBindings(v1, v2, v3); [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[v1]-20-|" options:0 metrics:nil views:variableBindings]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[v2]-20-|" options:0 metrics:nil views:variableBindings]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[v3]-20-|" options:0 metrics:nil views:variableBindings]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-60-[v1]" options:0 metrics:nil views:variableBindings]]; //Combine v1, v2, v3 vertically [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[v1]-0-[v2]-0-[v3]" options:0 metrics:nil views:variableBindings]]; //Define constraint for v1, v2, v3 height self.constraintHeight1 = [NSLayoutConstraint constraintWithItem:v1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:v1 attribute:NSLayoutAttributeHeight multiplier:0 constant:VIEW_COLLAPSED_HEIGHT]; [self.view addConstraint:self.constraintHeight1]; self.constraintHeight2 = [NSLayoutConstraint constraintWithItem:v2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:v2 attribute:NSLayoutAttributeHeight multiplier:0 constant:VIEW_COLLAPSED_HEIGHT]; [self.view addConstraint:self.constraintHeight2]; self.constraintHeight3 = [NSLayoutConstraint constraintWithItem:v3 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:v3 attribute:NSLayoutAttributeHeight multiplier:0 constant:VIEW_COLLAPSED_HEIGHT]; [self.view addConstraint:self.constraintHeight3]; } @end 

当您想要展开/折叠视图时,可以更改值constraint.constant:

 - (IBAction)clickedBtnExpand:(id)sender { [UIView animateWithDuration:0.5 animations:^{ self.constraintHeight1.constant = VIEW_EXPANDED_HEIGHT; [self.view layoutIfNeeded]; }]; } - (IBAction)clickedBtnCollapse:(id)sender { [UIView animateWithDuration:0.5 animations:^{ self.constraintHeight1.constant = VIEW_COLLAPSED_HEIGHT; [self.view layoutIfNeeded]; }]; }