gpt4 book ai didi

ios - 如何创建一个像 UILabel 一样具有 intrinsicContentSize 的 View ?

转载 作者:行者123 更新时间:2023-11-29 11:48:20 25 4
gpt4 key购买 nike

我想创建一个可根据内容自动调整大小的自定义 View 。

例如,我为 UILabel 设置了水平约束,然后它会自动换行。

请问在布局前系统是如何知道标签的宽度的?

我打印 updateConstraintslayoutSubviewsintrinsicContentSize 方法来尝试了解一切进展情况。

首先,我设置了 numberOfLine = 1,所以日志是这样的:

TagLabel will updateConstraints
TagLabel intrinsicContentSize 447.5 20.5
TagLabel did updateConstraints
TableViewCell will updateConstraints
TableViewCell did updateConstraints
TableViewCell will layoutSubviews
TableViewCell did layoutSubviews
TagLabel will layoutSubviews
TagLabel did layoutSubviews
TagLabel will layoutSubviews
TagLabel did layoutSubviews

然后我设置 numberOfLine = 0,日志变化如下:

TagLabel will updateConstraints
TagLabel intrinsicContentSize 428.0 20.5
TagLabel did updateConstraints
TableViewCell will updateConstraints
TableViewCell did updateConstraints

// extra calls
TagLabel will updateConstraints
TagLabel intrinsicContentSize 428.0 20.5
TagLabel did updateConstraints
TagLabel intrinsicContentSize 428.0 20.5
TagLabel intrinsicContentSize 371.0 41.0

TableViewCell will layoutSubviews
TableViewCell did layoutSubviews

// extra calls
TagLabel will updateConstraints
TagLabel intrinsicContentSize 428.0 20.5
TagLabel did updateConstraints
TagLabel will updateConstraints
TagLabel intrinsicContentSize 428.0 20.5
TagLabel did updateConstraints
TagLabel will updateConstraints
TagLabel intrinsicContentSize 371.0 41.0
TagLabel did updateConstraints
TagLabel will updateConstraints
TagLabel intrinsicContentSize 428.0 20.5
TagLabel did updateConstraints
TagLabel will updateConstraints
TagLabel intrinsicContentSize 371.0 41.0
TagLabel did updateConstraints

TagLabel will layoutSubviews
TagLabel did layoutSubviews
TagLabel will layoutSubviews
TagLabel did layoutSubviews

我发现系统在 layoutSubviews 之前正确计算标签的高度。

那么在 layoutSubviews 之前系统如何知道标签的宽度以便计算高度呢?

感谢。

最佳答案

首先,您需要清楚是要创建新的 UIView 还是子类 UILabel

您可以在不了解系统如何处理计算的情况下使用大量模板代码。我进一步假设您想从头开始制作自定义 View 。

对于此说明,我们将使用 UILabel 作为新自定义 View 的示例和指南。

您需要了解的是,通过设置 numberOfLines 属性,您可以更改 UILabel 中的计算处理方式。您可以通过单击测试项目中的 NOL 按钮来测试它。

创建自定义 View 时,您可以使用多种方法来计算位于自定义 View 子类中的自定义 View 的大小。要检查这一点,请转到 EXCustomLabelV 并查看:

override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {

控制台中的方法输出。您将看到第一个约束发生变化。该值将变为 566.667 而高度仍保持 24。结果是添加了文本截断的“...”。但是,如果您将 numberOfLines 属性设置为 0,则约束将变为 195.333 宽度和 71.6667 高度。

这里发生了一些重要的事情。系统将始终使用您的常量约束来计算您的自定义 View 大小/位置。但是在根据“外部”约束和“内部”设置计算(自定义 View 的) subview 时,您将不得不进行调整。

例如,EXCustomLabelV 的宽度始终为 200。无论。但是,内部 textRect 不会有那个大小。它有时会有大约 200,有时会超过 200,有时会更少。这些计算受 numberOfLines 的影响。我之所以告诉您,是因为您的自定义 View 中可能有一个图像,或者两个带有姓氏和姓氏的文本字段。

系统如何在布局前知道标签的宽度?它计算它。它首先通过检查宽度的最后一个约束(如果有的话)来询问“周围”。它向它的 subview (您的自定义类)询问其约束,然后进行计算。约束是规则。 AutoLayout 会在计算时检查这些规则。

系统如何知道标签的高度?它计算它。它首先检查 UILabel numberOfLines

在您的自定义 View 中,您应该有自定义的计算方法。在测试项目中你可以看到:

override func draw(_ rect: CGRect)

总是最后调用。完成所有计算后,您将获得 View 的最终大小。您将始终看到您的 View 宽度将等于最后一个宽度约束。

请随意使用我的测试项目进行您自己的计算,并了解 UILabel 无处理 View 大小计算。

创建自定义 View 时,您必须自己进行这些计算并手动更新尺寸和约束。然后系统应该能够轻松更新您的 View 。我建议您尝试自己计算 View 的帧大小。当您经历过这种“痛苦”时,您就会明白 AutoLayout 为您做了多少。

Test project repo link

关于ios - 如何创建一个像 UILabel 一样具有 intrinsicContentSize 的 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42342402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com