AutoLayoutdynamic.xib视图高度

我一直无法find与单独的.xib文件的AutoLayout的方式…

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

在这里输入图像说明

标题视图中的标签具有约束,这些约束将影响标题视图的垂直大小,并依次影响整个视图的大小。 子标题是一个0行的标签,意味着它是多行和dynamic的。 其他的东西都有一个设定的高度,对超级视图的水平约束和对兄弟的顶层约束(或者在标题视图的情况下是超视图)。

我遇到的问题是,当我在代码中加载这个.xib文件来显示时,高度总是基于Xcode的检查器中定义的静态。 是否有可能根据宽度(这会影响dynamic标签高度,因此影响视图的其余部分)使整个视图的高度dynamic变化?

例如,如果我从.xib加载这个视图并将它的宽度设置为300,那么我怎样才能调整它的高度来适应dynamic标签的新高度呢? 我是否需要使用intrinsicContentSize方法来定义这个大小?

经过多次实验和阅读,我find了答案。 当在某种构造函数中加载.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; } 

我相信有办法改善这一点,或者更好的方式来实现,但现在至less它的大小正确! 非常有用的视图不应该有用户定义的框架。

我被卡住,因为你是最好的仍然是计算全文时显示标签的高度。 如果你正在寻找,你会发现一个很好的解决scheme在这里: 如何findUILabel的线数 。

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

将所有内容embedded视图中 你的xib层次结构应该是:

  • 你的xib
    • 视图
      • 其他一切,你的标签,button等

视图的约束应该限制在顶层,引导和尾随到superview(你的xib),并且在你的“其他”内部,应该有一个对象的底层约束到超视图(视图)。

在你的代码中:

装入笔尖

nib.frame.size.width = 80 //在这里设置你想要的宽度

nib.label.text =“hello world”//在这里设置你的dynamic文本

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

nib.frame.size.height = nib.view.frame.height + 16 // 16是自动布局的最大缺口和最小缺口的总和

对于我的情况,我将这个xib加载到集合视图的单元格中,xib的高度将被dynamic调整,并且宽度将跟随单元格的宽度。 最后,上面的代码块在集合视图的cellForItemAt方法中。

希望能帮助到你。