在 TextField 中显示文本的准确高度

show a exactly Height of text in a TextField

我必须为配镜师编写视力测试程序。所以他们需要数字正好有一个特定的高度。 他有一个 IPad ans 流式传输到电视。我知道我必须考虑电视的 PPI。这是我的代码:

func calcPoints() -> Float {
    // he gives the Visus with a TextField
    let visus = Float(textFieldVisus.text!)
    // Here you put in the PPI of the device
    let ppi = Float(textFieldDPI.text!)
    // Calculate the lenght of the Number
    let lenght = ((0.29 * 5) / visus!) * 5
    // Calculate the Points (because TextFiels work with Points)
    let points = ((ppi! / 25.4) * lenght) * 0.75
    // here you divide with 2 because you have a retina Display on the IPad
    return (points / 2)
}

func passeUIan() {
    // Now i can give the Points to the TextField
    textField1.bounds.size.width = CGFloat(calcPoints())
    textField1.bounds.size.height = CGFloat(calcPoints())
    textField1.font = UIFont(name: (textField1.font?.fontName)!, size: CGFloat(calcPoints()))
}

但是当我在电视上测量长度时,它是错误的。 通常它必须是 7.25 毫米,但它大约是 9 毫米。 我不知道出了什么问题。我从 2 周开始搜索这个问题...

您需要先熟悉different font metrics。字体大小通常(但不总是)是上部和下部之间的差异。为了您的目的,大写字母的高度称为 "cap height",小写字母的高度称为 "x-height".

没有将字体大小转换为大写高度或 x 高度的公式。它们的关系不同于字体与字体,甚至字体内的变体(粗体、斜体、小型大写字母、显示、书籍)。

下面的函数使用二进制搜索来查找与您想要的高度(以英寸为单位)相匹配的磅值:

// desiredHeight is in inches
func pointSize(inFontName fontName: String, forDesiredCapHeight desiredHeight: CGFloat, ppi: CGFloat) -> CGFloat {
    var minPointSize: CGFloat = 0
    var maxPointSize: CGFloat = 5000
    var pointSize = (minPointSize + maxPointSize) / 2

    // Finding for exact match may not be possible. UIFont may round off
    // the sizes. If it's within 0.01 in (0.26 mm) of the desired height,
    // we consider that good enough
    let tolerance: CGFloat = 0.01

    while let font = UIFont(name: fontName, size: pointSize) {
        let actualHeight = font.capHeight / ppi * UIScreen.main.scale

        if abs(actualHeight - desiredHeight) < tolerance {
            return pointSize
        } else if actualHeight < desiredHeight {
            minPointSize = pointSize
        } else {
            maxPointSize = pointSize
        }

        pointSize = (minPointSize + maxPointSize) / 2
    }

    return 0
}

示例:找出使 Helvetica 大写字母高 1 英寸的磅值。 (326是iPhone6 / 6S / 7的PPI,我曾经测试过):

let size = pointSize(inFontName: "Helvetica", forDesiredCapHeight: 1, ppi: 326)
label.font = UIFont(name: fontName, size: size)
label.text = "F"

(提示:UILabelUITextField 更好地处理字体大小)