2

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

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

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

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

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

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

我正在做这个

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]>

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

4

2 回答 2

2

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

如果不涉及其他约束,只需更改要展开或折叠的视图的高度即可。

Apple 文档中所述,如果您自己设置所有约束,您可能应该调用,setTranslatesAutoresizingMaskIntoConstraints:NO否则您的显式约束将与隐式添加的 Autoresizing Mask 约束冲突,这看起来就像在这种情况下发生的事情。

编辑:看到上面列出所有约束的编辑,它证实了我的意思。通过翻译自动调整大小掩码添加的约束与您的自动布局约束冲突。他们明确地将每个视图的中心 Y 位置与父视图相关联。尝试setTranslatesAutoresizingMaskIntoConstraints:NO并根据需要设置您需要的任何其他约束。

于 2013-06-24T09:42:05.807 回答
0

当使用自动布局时,如果你想重新布局视图,你应该改变约束而不是视图的框架。
你可以参考这个示例:

#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];
    }];
}
于 2014-09-20T16:29:39.740 回答