我无法通过单个 .xib 文件找到很多 AutoLayout 方式...
I've not been able to find much in the way of AutoLayout with individual .xib files...
我有一个独立的 .xib 文件,它有 3 个视图 - 一个标题视图(包含两个标签)、一个输入和一个页脚(包含两个按钮).它看起来像这样:
I've got a standalone .xib file that has 3 views - a header view (which contains two labels), an input, and a footer (which contains two buttons). It looks like this:
标题视图中的标签具有约束,这些约束会影响标题视图的垂直大小,进而影响整个视图的大小.副标题是一个 0 行的标签,这意味着它是多行和动态的.其他所有东西都有一个固定的高度,水平约束到超级视图和顶部约束到兄弟(或标题视图中的超级视图).
The labels in the header view have constraints which should affect the vertical size of the header view, and in turn the size of the entire view. The subheader is a label with 0 lines, which means it is multi-line and dynamic. Everything else has a set height with horizontal constraints to superview and top constraints to sibling (or superview in header view's case).
我遇到的问题是,当我在代码中加载此 .xib 文件以进行显示时,高度始终是静态的,基于 Xcode 检查器中定义的内容.是否可以根据宽度使整个视图的高度动态化(这会影响动态标签高度并因此影响视图的其余部分)?
The issue I am having is that when I load this .xib file in code for display, the height is always static based on what is defined in Xcode's inspectors. Is it possible to make the height of the entire view dynamic based on the width (which affects dynamic label height and therefore rest of the view)?
例如 - 如果我从 .xib 加载此视图并将其宽度设置为 300,那么我如何让它调整其高度以适应动态标签的新高度?我需要使用 intrinsicContentSize
方法来定义这个尺寸吗?
For example - if I load this view from the .xib and set its width to 300, how do I then have it resize its height to accommodate the dynamic label's new height? Do I need to use the intrinsicContentSize
method to define this size?
经过大量的实验和阅读,我找到了答案.在某种构造函数中加载 .xib 时(在我的情况下是类级别的便捷方法),您必须确保调用 [view setTranslatesAutoresizingMaskIntoConstraints:NO];
例如,我做了以下:
After much experimentation and reading, I have found the answer. When loading the .xib in some sort of constructor (in my case a class level convenience method), you must make sure to call [view setTranslatesAutoresizingMaskIntoConstraints:NO];
For example, I've done the following:
+ (InputView *)inputViewWithHeader:(NSString *)header subHeader:(NSString *)subHeader inputValidation:(ValidationBlock)validation
{
InputView *inputView = [[[NSBundle mainBundle] loadNibNamed:@"InputView" owner:self options:nil] lastObject];
if ([inputView isKindOfClass:[InputView class]]) {
[inputView setTranslatesAutoresizingMaskIntoConstraints:NO];
[inputView configureWithHeader:header subHeader:subHeader inputValidation:validation];
[inputView layoutIfNeeded];
[inputView invalidateIntrinsicContentSize];
return inputView;
}
return nil;
}
然后,需要重写 layoutSubviews
和 intrinsicContentSize
.覆盖 layoutSubviews
允许我设置标签的 preferredMaxLayoutWidth
,而覆盖 intrinsicContentSize
允许我根据约束和子视图计算大小!这是我的实现:
Then, it's necessary to override layoutSubviews
and intrinsicContentSize
. Overriding layoutSubviews
allows me to set the preferredMaxLayoutWidth
of my label, while overriding intrinsicContentSize
allows me to calculate the size based on constraints and subviews! Here is my implementation of those:
- (void)layoutSubviews {
[super layoutSubviews];
self.subHeaderLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
[super layoutSubviews];
}
- (CGSize)intrinsicContentSize {
CGFloat height = self.headerView.bounds.size.height;
height += self.headerInputSpacer.constant;
height += self.inputField.bounds.size.height;
height += self.inputButtonSpacer.constant;
height += self.buttonView.bounds.size.height;
CGSize size = CGSizeMake([UIScreen mainScreen].bounds.size.width - 20, height);
return size;
}
我确信有办法改进这一点,或者有更好的方法来实现它,但现在至少它的大小是正确的!对于不应具有用户定义框架的视图非常有用.
I'm sure there are ways to improve this, or better ways to make it happen, but for now it is at least sized correctly! Very useful for views that should not have user-defined frames.
这篇关于AutoLayout 动态 .xib 视图高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!