计算点的大小以适合矩形内的字符串

时间:2018-06-21 09:12:49

标签: ios swift uikit core-graphics uigraphicscontext

我正在创建将文本放在图像顶部的东西。后端指定了允许绘制的最大文本框,我必须尽力适应用户在该矩形中输入的任何文本。

我查找了很多旧答案,但是所有答案似乎要么使用UILabel自动拟合,要么仅使用强行强制String.boundingRect(with:options:attributes:context:)

我的最初想法是仅将文本矩形的高度用作点大小,但是除了不支持水平方向上太长的文本外,这似乎无法100%起作用。

这是我现在正在绘制内容的方式,只是为了获得一些背景信息。

    let image = renderer.image { context in            
        backgroundImage.draw(at: .zero)

        let titleAttributes: [NSAttributedStringKey: Any] = [
            .font: UIFont(name: fontName, size: maxSize.height)!,
            .foregroundColor: UIColor.white,
            .paragraphStyle: NSMutableParagraphStyle(alignment: alignment),
            .shadow: NSShadow( color: .black, offset: .zero, radius: 28),
        ]

        (title as NSString).draw(with: maxFrame,
                                 options: .usesLineFragmentOrigin,
                                 attributes: titleAttributes,
                                 context: nil)
    }

有没有一种有效的方法可以计算出字体的点大小以适合矩形,而无需使用UILabel或强行使用它?

1 个答案:

答案 0 :(得分:2)

我自己又解决了!

我正在绘制的文本不允许换行,因此始终为一行。在Playgrounds中制作暴力破解方法时,我注意到文本宽度与字体大小成线性关系。这样就很容易。

extension UIFont {
    convenience init?(named fontName: String, fitting text: String, into targetSize: CGSize, with attributes: [NSAttributedStringKey: Any], options: NSStringDrawingOptions) {
        var attributes = attributes
        let fontSize = targetSize.height

        attributes[.font] = UIFont(name: fontName, size: fontSize)
        let size = text.boundingRect(with: CGSize(width: .greatestFiniteMagnitude, height: fontSize),
                                     options: options,
                                     attributes: attributes,
                                     context: nil).size

        let heightSize = targetSize.height / (size.height / fontSize)
        let widthSize = targetSize.width / (size.width / fontSize)

        self.init(name: fontName, size: min(heightSize, widthSize))
    }
}

此扩展名将启动一种字体,该字体可以保证在目标矩形内,只要为1行即可。