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

Posted

技术标签:

【中文标题】如何在 Swift 中设置自定义视图的内在内容大小?【英文标题】:How to set a custom view's intrinsic content size in Swift? 【发布时间】:2016-07-16 19:06:13 【问题描述】:

背景

我正在制作一个垂直标签,用于传统的蒙古文字。在我只是旋转UILabel 之前,但存在一些性能问题和其他并发症。现在我正在从头开始制作标签。但是,我需要垂直标签在其高度调整时告诉自动布局(基于字符串长度)。

我读过的内容

我阅读了Intrinsic Content Size 和Views with Intrinsic Content Size 文档。不过,这些更多的是关于如何使用它,而不是如何在自定义视图中定义它。

搜索“自定义视图的 ios 固有内容大小”只会给我

Proper usage of intrinsicContentSize and sizeThatFits: on UIView Subclass with autolayout

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

我正在尝试什么

我正在尝试的是下面的答案。我正在添加这个问答对,这样其他人就不会像我使用我使用的搜索关键字那样花时间找到答案。

【问题讨论】:

【参考方案1】:

设置自定义视图的内在内容大小可以让自动布局知道该视图想要多大。为了设置它,您需要覆盖intrinsicContentSize

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

然后调用

invalidateIntrinsicContentSize()

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

备注

Swift 3 更新:Easier Auto Layout: Coding Constraints in iOS 9 仅仅因为您在自定义视图中设置了内在内容大小并不意味着它会按您的预期工作。使用方法请阅读the documentation,特别注意Content-Hugging and Compression-Resistance。 也感谢这个问答让我走上正轨:How can I add padding to the intrinsic content size of UILabel? 也感谢this article 和documentation 对invalidateIntrinsicContentSize() 的帮助。

【讨论】:

对我来说,需要添加 @IBDesignable 才能让 Xcode 尊重内容大小。【参考方案2】:

“具有固有高度的视图”示例 ...

@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
    

    override func prepareForInterfaceBuilder() 
         invalidateIntrinsicContentSize()
    

您可以将其设置为可检查的

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

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

相比之下,如果它是一个没有固有高度的普通视图,则必须添加一个高度锚,否则它会崩溃:

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

请注意,在 ...

堆栈视图的重要特例:

您只设置了 ONE 锚点(对于垂直堆栈视图,高度;对于水平宽度)

因此,设置固有高度非常有效,因为:

固有高度确实意味着如果需要,将自动设置高度锚点。

请记住,在子视图的所有正常情况下,都需要许多其他锚点。

【讨论】:

我建议返回 super.intrinsicContentSize.width 作为覆盖中的宽度,而不是像你建议的那样返回一个常量。这样,当视图在堆栈视图之外使用并且具有遵守该约束的宽度约束时。 hi @VojtaBöhm - 当然可以,但这里的教学法是为了解释,事实上,当在忽略宽度值的布局情况下使用宽度值时(示例中的堆栈视图) )

以上是关于如何在 Swift 中设置自定义视图的内在内容大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 4 中的 UserDefalts 中设置自定义类数组数据

如何在summernote中设置自定义字体大小列表?

在 Swift 中设置自定义 NavigationBar 的最简单方法是啥?

如何在 mPDF 中设置自定义页面大小? Mpdf版本7

无法在 MapView,Swift 3 中设置自定义图钉图像

从数组中设置自定义单元格 uibutton 标题 - Swift