以编程方式的子视图约束

时间:2015-09-09 11:24:14

标签: ios constraints

我想以编程方式对电子邮件字段进行约束。但它不起作用。

图片描述: 有一个TopView。在那里,白框是TopInnerView。最后,如果我在EmailTextField中添加TopInnerView。它显示错误。

这是我的代码:

//MainView
    MainView = [[UIView alloc]initWithFrame:CGRectMake(0, 0,self.view.frame.size.width, self.view.frame.size.height)];
    MainView.backgroundColor = [UIColor whiteColor];
    [MainView setTranslatesAutoresizingMaskIntoConstraints:NO];
     [self.view addSubview:MainView];

//TopView
TopView = [[UIView alloc]init];
TopView.backgroundColor = [UIColor groupTableViewBackgroundColor];
[MainView addSubview:TopView];
[TopView setTranslatesAutoresizingMaskIntoConstraints:NO];

//TopInnerView
TopInnerView = [[UIView alloc]init];
TopInnerView.backgroundColor = [UIColor redColor];
[TopView addSubview:TopInnerView];
[TopInnerView setTranslatesAutoresizingMaskIntoConstraints:NO];

//EmailTextField
EmailTextField = [[UITextField alloc]init];
//WithFrame:CGRectMake(10, 0, 270, 40)];
EmailTextField.borderStyle = UITextBorderStyleRoundedRect;
[TopInnerView addSubview:EmailTextField];
id views = @{
                     @"TopView": TopView,
                     @"TopInnerView": TopInnerView,
                     @"CenterView":CenterView,
                     @"BottomView": BottomView,
                     @"EmailTextField":EmailTextField
                     };

// TopView constraints
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[TopView(320)]" options:0 metrics:nil views:views]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:TopView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:TopView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:110]];
//[self.view addConstraint:[NSLayoutConstraint constraintWithItem:TopView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
NSLayoutConstraint *TopViewHeightConstraint = [NSLayoutConstraint constraintWithItem:TopView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:170.0];
[self.view addConstraint:TopViewHeightConstraint];


// TopInnerView constraints
[TopView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[TopInnerView]-20-|" options:0 metrics:nil views:views]];
[TopView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[TopInnerView(80)]" options:0 metrics:nil views:views]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:TopInnerView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:TopView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];
[TopView addConstraint:[NSLayoutConstraint constraintWithItem:TopInnerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:TopView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
//[TopView addConstraint:[NSLayoutConstraint constraintWithItem:TopInnerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:TopView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];

//EmailTextField Constriants
//[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[EmailTextField(270)]" options:0 metrics:nil views:views]];
//Leading Constriant
NSLayoutConstraint *Leading = [NSLayoutConstraint
                                constraintWithItem:EmailTextField
                                attribute:NSLayoutAttributeTrailing
                                relatedBy:NSLayoutRelationEqual
                                toItem:self.view
                                attribute:NSLayoutAttributeTrailing
                                multiplier:1.0
                                constant:10.0];

//Trailing Constriant
    NSLayoutConstraint *Trailing = [NSLayoutConstraint
                                   constraintWithItem:EmailTextField
                                   attribute:NSLayoutAttributeTrailing
                                   relatedBy:NSLayoutRelationEqual
                                   toItem:self.view
                                   attribute:NSLayoutAttributeTrailing
                                   multiplier:1.0
                                   constant:0.0];

    [self.view addConstraint:Leading];
    [self.view addConstraint:Trailing];

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:EmailTextField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:TopInnerView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];
NSLayoutConstraint *EmailTextFieldHeightConstraint = [NSLayoutConstraint constraintWithItem:EmailTextField attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:40.0];
[self.view addConstraint:EmailTextFieldHeightConstraint];

1 个答案:

答案 0 :(得分:0)

可以肯定的是,程序化约束可能是一个微妙的事情,它们可以让你发疯。话虽如此,我看到这里发生的一些事情会让我感到紧张,如果这是我的设计。

首先,您要创建每个视图并将每个视图作为子视图添加到您刚创建的视图中(这不一定是错误的)。然后,您将每个视图约束与相应的父视图相关联 - 除了EmailTextField,您将前两个约束与self.view相关联。

接下来,您的Leading约束正在使用NSLayoutAttributeTrailing属性;我打赌这是一个错字,应该是NSLayoutAttributeLeading。没有看到你的错误我不能确定,但​​我打赌你需要将EmailTextView的前两个关系改为这样的:

//EmailTextView
[TopInnerView addSubview:EmailTextField];
NSLayoutConstraint *Leading = [NSLayoutConstraint
                                constraintWithItem:EmailTextField
                                attribute:NSLayoutAttributeLeading
                                relatedBy:NSLayoutRelationEqual
                                toItem:TopInnerView
                                attribute:NSLayoutAttributeTrailing
                                multiplier:1.0
                                constant:10.0];

//Trailing Constraint
    NSLayoutConstraint *Trailing = [NSLayoutConstraint
                                   constraintWithItem:EmailTextField
                                   attribute:NSLayoutAttributeTrailing
                                   relatedBy:NSLayoutRelationEqual
                                   toItem:TopInnerView
                                   attribute:NSLayoutAttributeTrailing
                                   multiplier:1.0
                                   constant:0.0];

然后将这两个作为约束添加到self.view,考虑到如何定义这些约束,这将是一致的。但是,您最终在EmailTextFieldInnerTopView之间定义了两个约束,并将这些约束添加到self.view,这与您之前的操作方式不一致。使用您现有的设计,我会尝试

[TopInnerView addConstraint:Leading];
[TopInnerView addConstraint:Trailing];

接受同样的一致性处理可以使您的最后两个限制受益;我会把它留给你作为练习。

总的来说,我认为用户界面可能只是在阻碍所有嵌入式约束。如果这些调整没有帮助,我建议您将代码返回到您首次定义EmailTextField对象的位置。然后逐个处理每个约束,以确保您始终定义每个约束。最后,每次将一个添加到UI层次结构中,确保您的方法也一致。最终,您会找到导致问题的约束。