如何在Swift中设置自定义视图的内容大小?

背景

我正在制作一个垂直的标签,用于传统的蒙古文字。 在我刚刚旋转UILabel ,有一些性能问题和其他复杂性。 现在我正在从头开始制作标签。 但是,我需要垂直标签来告诉自动布局当它的高度调整(基于string长度)。

我读过的

我使用内置内容大小文档阅读了内部内容大小和视图 。 但是,这些更多的是关于如何使用它,而不是如何在自定义视图中定义它。

search“自定义视图的ios内在内容大小”只给我

  • 正确使用intrinsicContentSize和sizeThatFits:在具有自动布局的UIView子类上

在堆栈溢出。 这个特定的问题甚至不需要内在的内容大小,因为他们的观点只是一个标准视图的集合。

我正在尝试

我正在尝试的是我的答案。 我添加了这个问答对,这样就不会让其他人花很长时间才能find答案,因为它使用了我使用的search关键字。

设置自定义视图的内在内容大小可以让自动布局知道视图的大小。 为了设置它,你需要重写intrinsicContentSize

 override var intrinsicContentSize: CGSize { return CGSize(width: x, height: y) } 

然后打电话

 invalidateIntrinsicContentSize() 

每当您的自定义视图的内在内容大小发生变化并且框架应该更新时。

笔记

  • Swift 3更新 : 更简单的自动布局:iOS 9中的编码约束

  • 阅读使用Swift和Auto Layout为iOS 8编写自定义控件 ,了解如何在上下文中正确完成此操作的示例。

  • 仅仅因为您在自定义视图中设置的内容内容大小并不意味着它将按照您的预期工作。 阅读文档以了解如何使用它,特别注意内容拥抱和压缩阻力 。
  • 还要感谢这个问题和答案,让我走上正轨: 如何将填充添加到UILabel的固有内容大小?
  • 还要感谢本文以及有关invalidateIntrinsicContentSize()帮助文档 。

基于上面的优秀答案,

“具有内在高度的视图”的示例…

 @IBDesignable class HView: UIView { @IBInspectable var height: CGFloat = 100.0 override var intrinsicContentSize: CGSize { return CGSize(width: 99, height: height) // if using in, say, a vertical stack view, the width is ignored } } 

在这里输入图像说明

您可以设置为可检查的

在这里输入图像说明

由于它具有固有的高度,因此可以(例如)以代码的forms立即插入堆栈视图中:

 stack?.insertArrangedSubview(HView(), at: 3) 

相反,如果这是一个没有内在高度的普通视图,则必须添加一个高度锚,否则将会崩溃:

 let v:UIView = HView() v.heightAnchor.constraint(equalToConstant: 100).isActive = true stack?.insertArrangedSubview(v, at: 3) 

在堆栈视图的特殊情况下,您只需要担心只有一个锚点(对于垂直堆栈视图,高度),因此设置内在高度可以很好地工作; 因为内在高度确实意味着如果需要的话,高度锚将专门设置。 (记住,在子视图的所有正常情况下,需要许多其他的锚。

Interesting Posts