我知道你的问题,因为我也曾遇到过自定义字体的问题。我将提供两种解决方案。在我的项目中,我采用了你建议的方法,重写intrinsicContentSize并添加高度和宽度的填充倍增器。在我的情况下,字体是面向用户的,所以我有一个结构体来保存所有相关信息。FYI,Chalkduster在系统中且会被裁剪。我也相信这都是由字体文件本身引起的。
解决方案1:
示例:
struct UserFont{
var name : String
var displayName : String
var widthMultiplier : CGFloat
var heightMultiplier : CGFloat
}
然后在我的UILabel中,我将其子类化以使用这两个度量标准
@IBDesignable
class MultiplierUILabel: UILabel {
@IBInspectable var widthPaddingMultiplier : CGFloat = 1
@IBInspectable var heightPaddingMultiplier : CGFloat = 1
override var intrinsicContentSize: CGSize{
return CGSize(width: super.intrinsicContentSize.width * widthPaddingMultiplier, height: super.intrinsicContentSize.height * heightPaddingMultiplier)
}
}
这对我来说是最简单的实现,因为我找到了相应的字体和倍增器比例。
解决方案2:
通过测量字形边界并调整原点y,您可能能够使绘图稍微高一些。例如,这可以修复系统中包含的Chalkduster字体的剪切问题。
@IBDesignable
class PaddingUILabel: UILabel {
override func drawText(in rect:CGRect) {
guard let labelText = text else { return super.drawText(in: rect) }
let info = boundsForAttrString(str: labelText, font: self.font!, kern: .leastNormalMagnitude)
let glyph = info.glyph
var newRect = rect
let glyphPadding = -(glyph.origin.y)
if glyphPadding - info.descent > 1 && info.descent != 0{
newRect.origin.y -= glyphPadding/2
}else{
if info.descent != 0{
newRect.origin.y += (info.descent - glyphPadding)/2
}
}
super.drawText(in: newRect)
}
func boundsForAttrString(str:String,font:UIFont,kern:CGFloat)->(glyph:CGRect,descent:CGFloat){
let attr = NSAttributedString(string: str, attributes: [.font:font,.kern:kern])
let line = CTLineCreateWithAttributedString(attr)
var ascent : CGFloat = 0
var descent : CGFloat = 0
var leading : CGFloat = 0
CTLineGetTypographicBounds(line, &ascent, &descent, &leading)
let glyph = CTLineGetBoundsWithOptions(line, .useGlyphPathBounds).integral
return (glyph,leading != 0 ? descent : 0)
}
}
解决方案2的结果:
系统
![System](https://istack.dev59.com/Vd3YG.webp)
使用字形边界的PaddingUILabel
![PaddingUILabel](https://istack.dev59.com/T0YlD.webp)