swift: 以编程方式创建 UILabel 固定宽度,根据文本长度垂直调整大小
swift: programmatically create UILabel fixed width that resizes vertically according to text length
我看过涉及自动布局的垂直调整大小的答案,但我创建的 UILabel
s 仅在运行时需要。 (我可能需要从零到许多这样的标签。)
示例(忽略颜色)
- 短文本(注意与长文本相同的宽度):
- 较长的文本(注意与较短的文本示例相同的宽度,添加文本的行数更多):
如果文本可以容纳在固定宽度的一行中,则标签不需要垂直调整大小。但是如果有更多的字符,标签应该继续垂直扩展以适应这些额外的字符。文本应逐行环绕。文本应从标签的左上角开始。
更具体地说:
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。您也可以使用自动布局约束来解决您的问题,但我不太喜欢以编程方式使用它们。
我看过涉及自动布局的垂直调整大小的答案,但我创建的 UILabel
s 仅在运行时需要。 (我可能需要从零到许多这样的标签。)
示例(忽略颜色)
- 短文本(注意与长文本相同的宽度):
- 较长的文本(注意与较短的文本示例相同的宽度,添加文本的行数更多):
如果文本可以容纳在固定宽度的一行中,则标签不需要垂直调整大小。但是如果有更多的字符,标签应该继续垂直扩展以适应这些额外的字符。文本应逐行环绕。文本应从标签的左上角开始。
更具体地说:
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。您也可以使用自动布局约束来解决您的问题,但我不太喜欢以编程方式使用它们。