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

adjustsFontSizeToFitWidth has different effect on UILabel than on UITextField

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

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

UITextField.adjustsFontSizeToFitWidth 的文档明确指出:

Normally, the text field’s content is drawn with the font you specify in the font property. If this property is set to true, however, and the contents in the text property exceed the text field’s bounding rectangle, the receiver starts reducing the font size until the string fits or the minimum font size is reached. The text is shrunk along the baseline.

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

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

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

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

它也主要用于字符串宽度

此外,UILabelUITextField 不使用相同的字体渲染,并且没有相同的边界框(文本字段有内嵌)。

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