如何使用iOS 6中的多个子视图自动布局现有的自定义视图

我想使用约束的布局,但我有许多内部嵌套Subviews的自定义控件。 而且我将约束添加到顶视图(CustomView),但没有正确布置子视图。

防爆。 我有TextFieldWithLabel类,它显示上方和下方的标签,我创build了TextFieldWithLabel实例的UITextField,并添加到具有约束的超级视图。

但没有按预期显示结果。 虽然它的可见,但不是我想要的地方。为此我不想改变整个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

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

文本字段和标签仍然是可见的,因为你说你没有在这个控件的内部使用自动布局 – 大概你可以在里面设置一些框架和自动调整掩码。 因此,文本字段和标签超出​​了TextFieldWithLabel的范围,因此它们是可见的,但可能不会对触摸做出响应。

要解决这个问题,你有两个select:

  • 内部使用自动布局 – 例如,如果你有这个约束(VFL),那么它会自动给你的控制一个高度: "V:|-[label]-[textField]-|"
  • 在上面的代码中添加大小限制 – 使用您在initWithFrame中执行的相同大小。 这里是一个设置高度:

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

我在UIView上有一个类别来简化这里常见约束的创build。 使用类别代码你可以做centerInView:constrainToSize:

如果你不想你的标签(或其他子视图)有resize的限制,然后…

  self.YourLabel.translatesAutoresizingMaskIntoConstraints = NO; 

不知道你如何处理TextFieldWithLabel,它可能不清楚,它实际上是一个UIView子类(我总是命名UIView子类以视图结束)

在这种情况下,您最终会在构build应用程序时遇到一个鬼祟的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的约束表单传递给TextFieldWithLabel_ View _

在Storyboard中勾选“AutoResize Subviews”

希望有所帮助。

PS不要放弃AutoLayout …掌握它!