我正在尝试使用约束来制作布局,但我有许多带有内部嵌套子视图的自定义控件。我将约束添加到顶视图(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。
答案 0 :(得分:3)
在自动布局下,您的框架尺寸将被忽略(您在initWithFrame:
期间使用的尺寸)。您已指定了定位约束,但与大小无关,因此您的TextFieldWithLabel
位于屏幕中央,大小为零。
文本字段和标签仍然可见,因为您说您没有在此控件内部使用自动布局 - 可能是您在那里设置了一些框架和自动调整遮罩。因此,文本字段和标签超出TextFieldWithLabel
的范围,因此它们是可见的,但可能不响应触摸。
要解决此问题,您有两种选择:
"V:|-[label]-[textField]-|"
为您的代码添加大小限制 - 使用您在initWithFrame中执行的相同维度。这是一个设置高度:
[NSLayoutConstraint constraintWithItem:usernameTextField
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:0.0
constant:50.0];
我在UIView上有一个类别来简化常见约束here的创建。使用类别代码,您可以执行centerInView:
和constrainToSize:
答案 1 :(得分:0)
如果您不希望您的标签(或其他子视图)具有调整大小限制,那么......
self.YourLabel.translatesAutoresizingMaskIntoConstraints = NO;
答案 2 :(得分:0)
不确定你是如何处理TextFieldWithLabel的,我可能不清楚它实际上是一个UIView子类(我总是命名以View结尾的UIView子类)
在这种情况下,你最终得到了一个偷偷摸摸的视图,它在构建应用程序时介于两者之间。在InterfaceBuilder中,您在View中拖动,并可能将类设置为“TextFieldWithLabel_ View _ ”。你做了通常的“自定义约束”但是,如果“TextFieldWithLabel_ View _ ”类已从UIView中继承,则引入了一个中间层。
在布局标签和文本字段的XIB或代码中,您可能已经设置了与您自己的子类的UIView相对应的正确约束。
问题是,子类UIView的约束没有链接到使用StoryBoard拖入的View。
这就是我所做的:
@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”
希望有所帮助。
P.S。不要放弃AutoLayout ......掌握它!