0

我正在尝试使用约束来制作布局,但我有许多带有内部嵌套子视图的自定义控件。我正在将约束添加到顶视图(CustomView),但它没有正确布置子视图。

前任。我有 TextFieldWithLabel 类,它在 UITextField 的顶部和下方显示标签,我正在创建 TextFieldWithLabel 的实例并添加到带有约束的超级视图。

但它没有按预期显示结果。虽然它是可见的,但没有放在我想要的位置。为此,我不想更改整个 TextFieldWithLabel 类的敌人自动布局。

请帮忙!

usernameTextField = [[TextFieldWithLabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50) name:@"UserName"];
    [usernameTextField setTranslatesAutoresizingMaskIntoConstraints:NO];
    [superview addSubview:usernameTextField];
    NSLayoutConstraint* myConstraint = [NSLayoutConstraint constraintWithItem:usernameTextField
                                                                    attribute:NSLayoutAttributeCenterY
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:superview
                                                                    attribute:NSLayoutAttributeCenterY
                                                                   multiplier:1
                                                                     constant:0];

    [superview addConstraint:myConstraint];

    myConstraint = [NSLayoutConstraint constraintWithItem:usernameTextField
                                                attribute:NSLayoutAttributeCenterX
                                                relatedBy:NSLayoutRelationEqual
                                                   toItem:superview
                                                attribute:NSLayoutAttributeCenterX
                                               multiplier:1
                                                 constant:0];
    [superview addConstraint:myConstraint];

屏幕截图:此处未居中,并且文本字段 (RedColor) 也不可点击。标签和文本字段位于 TextFieldWithLabel 内。请注意:TextFieldWithLabel 是 ComponentView 的子类,而 ComponentView 是 UIView 的子类。所以我怀疑这可能是问题所在?我是否也需要自动布局 ComponentsView。 UITextField

4

3 回答 3

3

在自动布局下,您的帧大小将被忽略(您在 期间使用的那个initWithFrame:)。您已经指定了定位约束,但与大小无关,因此您TextFieldWithLabel位于屏幕的中心,大小为零。

文本字段和标签仍然可见,因为您说您没有在此控件内部使用自动布局 - 大概您确实在那里设置了一些框架和自动调整大小的蒙版。因此,文本字段和标签超出​​了 的范围TextFieldWithLabel,因此它们是可见的,但可能不会响应触摸。

要解决此问题,您有两种选择:

  • 在内部使用自动布局 - 例如,如果您有此约束(在 VFL 中),那么它将自动为您的控件提供高度:"V:|-[label]-[textField]-|"
  • 在上面的代码中添加尺寸限制 - 使用与 initWithFrame 中相同的尺寸。这是一个用于设置高度的方法:

    [NSLayoutConstraint constraintWithItem:usernameTextField 
                                 attribute:NSLayoutAttributeHeight 
                                 relatedBy:NSLayoutRelationEqual 
                                    toItem:nil 
                                 attribute:NSLayoutAttributeNotAnAttribute 
                                multiplier:0.0 
                                  constant:50.0];
    

我在 UIView 上有一个类别来简化此处常见约束的创建。使用您要做的类别代码centerInView:constrainToSize:

于 2013-03-28T08:34:20.943 回答
0

不确定您如何处理 TextFieldWithLabel,我可能不清楚它实际上是 UIView 子类(我总是将 UIView 子类命名为以 View 结尾)

在这种情况下,您最终会在构建应用程序时得到一个偷偷摸摸的 View。在 InterfaceBuilder 中,您拖入了一个视图,并且可能将类设置为“TextFieldWithLabel_View_ 。您执行了通常的“自定义约束”,但是如果“TextFieldWithLabel_ View_ ”类已从 UIView 子类化,则您引入了一个中间层。

在您布局标签和文本字段的 XIB 或代码中,您可能已经相对于您自己的子类的 UIView 设置了正确的约束。

问题是,子类 UIView 的约束未链接到已随 StoryBoard 拖入的视图。

这是我所做的:

@interface TextFieldWithLabel__View__ ()
@property (strong, nonatomic) IBOutlet UIView *backgroundView;
@property (weak, nonatomic) IBOutlet UILabel *labelText;
....
....
@end



-(id)initWithCoder:(NSCoder *)decoder{
    if ((self = [super initWithCoder:decoder])){
        [self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"TextFieldWithLabel__View__" owner:self options:nil] objectAtIndex:0]];
    }

    // Set the backgroundView (the one needed for the IB to create a UIView for XIB)
    // Left, Right, Top and Bottom to 0

    _backgroundView.translatesAutoresizingMaskIntoConstraints = NO;
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundView
                                                     attribute:NSLayoutAttributeLeft
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeLeft
                                                    multiplier:0
                                                      constant:0
                         ]
     ];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundView
                                                     attribute:NSLayoutAttributeRight
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeRight
                                                    multiplier:1
                                                      constant:0
                         ]
     ];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundView
                                                     attribute:NSLayoutAttributeTop
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeTop
                                                    multiplier:0
                                                      constant:0
                         ]
     ];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundView
                                                     attribute:NSLayoutAttributeBottom
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeBottom
                                                    multiplier:1
                                                      constant:0
                         ]
     ];
    return self;
}

现在,当您想要重新定义 CustomView、拖动项目、调整分配区域的大小等时,它会很好地通过 CustomView 的约束表单到您TextFieldWithLabel_View_

并在情节提要中勾选“AutoResize Subviews”

希望有帮助。

PS 不要放弃 AutoLayout...掌握它!

于 2013-03-27T15:38:36.553 回答
0

如果您不希望您的标签(或其他子视图)具有调整大小约束,那么...

    self.YourLabel.translatesAutoresizingMaskIntoConstraints = NO;
于 2013-03-26T13:54:23.113 回答