adjustsFontSizeToFitWidth 对 UILabel 的影响与对 UITextField 的影响不同

Posted

技术标签:

【中文标题】adjustsFontSizeToFitWidth 对 UILabel 的影响与对 UITextField 的影响不同【英文标题】:adjustsFontSizeToFitWidth has different effect on UILabel than on UITextField 【发布时间】:2021-12-26 14:32:14 【问题描述】:

我设置了一个UILabel(名为label)和一个UITextField(名为textField),这样它们的帧大小相同,并且都启用了adjustsFontSizeToFitWidth。除此之外,我为textField 设置了minimumFontSize,并为labeltextField 设置了较大的初始字体大小。这应该 - 根据我阅读的内容 - 导致“自动缩小”包含文本的字体大小。到目前为止一切顺利。

事实上,这导致labeltextField 的文本缩小,但令我惊讶的是不同的结果。虽然label 字体会缩小以适应标签边界矩形,但textField 字体会缩小以适应textField 的宽度,而不是其高度。这是输出的图片(顶部为label,底部为textField):

UITextField.adjustsFontSizeToFitWidth 的文档明确指出:

通常,文本字段的内容是使用您在字体属性中指定的字体绘制的。但是,如果此属性设置为 true,并且 text 属性中的内容超出 文本字段的边界矩形,则接收器开始减小字体大小,直到字符串适合或达到最小字体大小。文本沿基线收缩。

这让我对textField 的收缩行为感到困惑。任何想法为什么会发生这种情况?我如何为textField 获得与label 相同的结果?

这是生成上述图像的完整 Playground 代码(我使用了自动布局,但是当我使用固定框架时也会发生同样的事情):

import Foundation
import UIKit
import PlaygroundSupport

// setup liveView
var viewSize = CGSize(width: 400.0, height: 600.0)
let liveView = UIView(frame: CGRect(origin: CGPoint.zero, size: viewSize))
liveView.backgroundColor = UIColor.green
let topView = UIView()
topView.translatesAutoresizingMaskIntoConstraints = false
liveView.addSubview(topView)
topView.topAnchor.constraint(equalTo: liveView.topAnchor).isActive = true
topView.leftAnchor.constraint(equalTo: liveView.leftAnchor).isActive = true
topView.rightAnchor.constraint(equalTo: liveView.rightAnchor).isActive = true
topView.heightAnchor.constraint(equalTo: liveView.heightAnchor, multiplier: 0.5).isActive = true
let bottomView = UIView()
bottomView.translatesAutoresizingMaskIntoConstraints = false
liveView.addSubview(bottomView)
bottomView.bottomAnchor.constraint(equalTo: liveView.bottomAnchor).isActive = true
bottomView.leftAnchor.constraint(equalTo: liveView.leftAnchor).isActive = true
bottomView.rightAnchor.constraint(equalTo: liveView.rightAnchor).isActive = true
bottomView.heightAnchor.constraint(equalTo: liveView.heightAnchor, multiplier: 0.5).isActive = true

PlaygroundPage.current.liveView = liveView

// setup label
let labelSize = 0.5 * CGSize(width: liveView.frame.width, height: liveView.frame.height)
let label = UILabel(frame: CGRect(origin: CGPoint(x: 0.5 * labelSize.width, y: 0.5 * labelSize.height), size: labelSize))
label.numberOfLines = 1
label.text = "0"
label.adjustsFontSizeToFitWidth = true
label.font = UIFont(name: "Helvetica", size: 1000.0)
label.backgroundColor = UIColor.blue
label.translatesAutoresizingMaskIntoConstraints = false
topView.addSubview(label)
label.centerXAnchor.constraint(equalTo: topView.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: topView.centerYAnchor).isActive = true
label.widthAnchor.constraint(equalTo: topView.widthAnchor, multiplier: 0.5).isActive = true
label.heightAnchor.constraint(equalTo: topView.heightAnchor, multiplier: 0.5).isActive = true

// setup textField
let textField = UITextField(frame: CGRect(origin: CGPoint(x: 0.5 * labelSize.width, y: 0.5 * labelSize.height), size: labelSize))
textField.text = "0"
textField.adjustsFontSizeToFitWidth = true
textField.minimumFontSize = 10.0
textField.font = UIFont(name: "Helvetica", size: 1000.0)
textField.backgroundColor = UIColor.blue
textField.translatesAutoresizingMaskIntoConstraints = false
bottomView.addSubview(textField)
textField.centerXAnchor.constraint(equalTo: bottomView.centerXAnchor).isActive = true
textField.centerYAnchor.constraint(equalTo: bottomView.centerYAnchor).isActive = true
textField.widthAnchor.constraint(equalTo: bottomView.widthAnchor, multiplier: 0.5).isActive = true
textField.heightAnchor.constraint(equalTo: bottomView.heightAnchor, multiplier: 0.5).isActive = true

【问题讨论】:

【参考方案1】:

我认为公平地说 .adjustsFontSizeToFitWidth = true 只有“大部分” 有效。

它也主要用于字符串width

另外,UILabelUITextField 不使用相同的字体渲染,也没有相同的边界框(文本字段有一个插入)。

如果您希望两个元素具有相同的视觉 行为,最好的办法是使用禁用用户交互的UITextField 而不是UILabel

【讨论】:

公平而诚实地符合我的预期。那么你认为adjustsFontSizeToFitWidth 上的UITextField 的文档是错误的吗?因为插入与否,文本似乎不适合边界矩形。 @Wizard - 我不是苹果工程师,所以我只能猜测。要么文档是错误的,要么就是不清楚。同样,我认为 主要用途 是用于字符串宽度...尤其是UITextField 使用文本字段的固有高度更为常见 - 基于字体 - 而不是调整基于受限文本字段高度的字体。

以上是关于adjustsFontSizeToFitWidth 对 UILabel 的影响与对 UITextField 的影响不同的主要内容,如果未能解决你的问题,请参考以下文章

adjustsFontSizeToFitWidth 与 NSLineBreakByCharWrapping 无法共用

自动布局在adjustsFontSizeToFitWidth 与fixedNumberOfLines 一起使用之前计算大小

现在是不是可以使用带有adjustsFontSizeToFitWidth 的Multiline UILabel?

adjustsFontSizeToFitWidth 或 boundingRectWithSize 何时更改 context.actualScaleFactor?

adjustsFontSizeToFitWidth 对 UILabel 的影响与对 UITextField 的影响不同

iOS 根据给定宽度自适应文字大小