AutoLayout Dynamic .xib查看高度

时间:2015-01-08 23:49:16

标签: ios objective-c autolayout

我无法通过单独的.xib文件找到AutoLayout的方式......

我有一个包含3个视图的独立.xib文件 - 标题视图(包含两个标签),一个输入和一个页脚(包含两个按钮)。它看起来像这样:

enter image description here

标题视图中的标签具有约束,这些约束应该影响标题视图的垂直大小,进而影响整个视图的大小。子标题是一个带有0行的标签,这意味着它是多行和动态的。其他所有东西都有一个设置高度,水平约束到superview和顶部约束兄弟(或标题视图中的superview')。

我遇到的问题是,当我在代码中加载此.xib文件进行显示时,根据Xcode的检查员定义的内容,高度始终是静态的。是否可以根据宽度使整个视图的高度动态变化(这会影响动态标签高度,从而影响视图的其余部分)?

例如 - 如果我从.xib加载此视图并将其宽度设置为300,那么我如何调整其高度以适应动态标签的新高度?我是否需要使用intrinsicContentSize方法来定义此大小?

2 个答案:

答案 0 :(得分:14)

经过多次实验和阅读,我找到了答案。在某种构造函数中加载.xib(在我的情况下是类级别的方便方法)时,必须确保调用[view setTranslatesAutoresizingMaskIntoConstraints:NO];例如,我已完成以下操作:

+ (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;
}

然后,有必要覆盖layoutSubviewsintrinsicContentSize。覆盖layoutSubviews允许我设置我的标签的preferredMaxLayoutWidth,而覆盖intrinsicContentSize允许我根据约束和子视图计算大小!以下是我的实现:

- (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;
}

我确信有很多方法可以改善这种情况,或者更好的方法来实现这一目标,但现在它的尺寸至少是正确的!对于不应具有用户定义帧的视图非常有用。

答案 1 :(得分:3)

这是我的方法(Swift版本):

将所有内容嵌入视图中。您的xib层次结构应为:

  • 你的xib
    • 查看
      • 其他所有内容,标签,按钮等。

View的约束应该限制为Top,Leading和Trailing to superview(你的xib),而在你的“其他所有”里面,应该有一个对象的superview底部约束(View)。

在您的代码中:

加载笔尖

nib.frame.size.width = 80 //在此处设置所需的宽度

nib.label.text =“hello world”//在此处设置动态文字

nib.layoutIfNeeded()//这将相应地计算和设置高度

nib.frame.size.height = nib.view.frame.height + 16 // 16是自动布局的顶部差距和底部差距的总和

对于我的情况,我将此xib加载到集合视图的单元格中,xib的高度将动态调整,宽度将遵循单元格的宽度。最后,上面的代码块位于集合视图的cellForItemAt方法中。

希望它有所帮助。