swift: 以编程方式创建 UILabel 固定宽度,根据文本长度垂直调整大小

swift: programmatically create UILabel fixed width that resizes vertically according to text length

我看过涉及自动布局的垂直调整大小的答案,但我创建的 UILabels 仅在运行时需要。 (我可能需要从零到许多这样的标签。)

示例(忽略颜色)

  1. 短文本(注意与长文本相同的宽度):

  1. 较长的文本(注意与较短的文本示例相同的宽度,添加文本的行数更多):

如果文本可以容纳在固定宽度的一行中,则标签不需要垂直调整大小。但是如果有更多的字符,标签应该继续垂直扩展以适应这些额外的字符。文本应逐行环绕。文本应从标签的左上角开始。

更具体地说:

let marker = GMSMarker(position: myLatLng)
// see  for imageWithView
marker.icon = imageWithView(label) // **how do i create this label?**
marker.map = map // map is a GMSMapView

这些标签可以在屏幕上的任何地方。这适用于地图应用程序,其中每个标签将放置在随机位置。标签的位置彼此没有关系。

将标签的 numberOfLines 属性 设置为零并使用约束固定标签的宽度(通过显式约束宽度或将前缘和后缘约束到其他视图,例如标签的超级视图)。然后标签将自动调整垂直大小以适合文本的高度。您需要通过其顶部约束来固定一个标签,以便视图系统知道从哪里开始布局,然后所有其他标签的顶部应该被约束到前一个标签的底部。这样他们都会相对于前一个标签的高度进行布局。

根据您的评论进行编辑:

您可以在 iOS 9 及更高版本上使用 widthAnchor 属性 显式设置视图的宽度。您可以使用 NSLayoutConstraints 在较旧的 iOS 版本上设置它(搜索 SO 以获取示例)。

例如:

label.widthAnchor.constraintEqualToConstant(50.0).active = true

这会将标签的宽度设置为 50 点宽,但不会固定其高度,因此使用 numberOfLines = 0 然后标签将在您设置文本时自动调整垂直大小。

UIView有两个有用的方法:sizeToFit() and sizeThatFits(_:)

第一个将视图调整为最小尺寸以适应子视图的内容,第二个根本不改变框架,但 returns 计算出的尺寸:(1) 适合所有子视图和 ( 2) 不超过参数size

因此您可以使用 sizeThatFits 来达到您的目的:

let label = UILabel()

override func viewDidLoad() {
    super.viewDidLoad()

    label.backgroundColor = UIColor.orange
    label.textColor = UIColor.white
//  label.text = "ultimate Frisbee"
    label.text = "ultimate Frisbee\nin 3 minutes,\nall welcome|2"
    label.numberOfLines = 10
    view.addSubview(label)

    updateLabelFrame()
}

func updateLabelFrame() {
    let maxSize = CGSize(width: 150, height: 300)
    let size = label.sizeThatFits(maxSize)
    label.frame = CGRect(origin: CGPoint(x: 100, y: 100), size: size)
}

输出:

P.S。您也可以使用自动布局约束来解决您的问题,但我不太喜欢以编程方式使用它们。