我使用的是自定义字体,并且渲染可能以某种方式使行高变高,这可能是由于descent
或leading
(?)配置错误所致,因此在渲染文本的最后一行中将g和j截断了。我认为这可能是特定字体的问题,因为Sketch也暴露了所涉及字体的类似问题,但是我觉得我对打印尺寸或字体的理解还不够。我发现Typographic Concepts上的此Apple文档页面非常有见地。
我第一次使用FontLab的测试版本检查了字体本身,这是我第一次使用-因此我几乎不知道我在看什么。似乎g处于配置的descent
之下,这似乎是最后一行。 (?)(请参阅:Character view in FontLab, showing the descend of the g)
通过lineSpacing
,我可以调整线条本身之间的距离,以将其固定在前几行中。我知道iOS 14将带来一种在SwiftUI中修改leading
的 Text
的方法。但是我需要以iOS 13为目标,所以这无济于事。
我还尝试了SwiftUI的Text
,具有自定义段落样式的常规UILabel.text
和UILabel.attributedText
,但是我没有进行任何调整似乎可以缓解此问题。
该 View 甚至没有剪切。仅向框架添加填充完全没有帮助。它增加了距离,但是g和j仍然被剪切。
我能做什么?当最后一行中有g和j时,将UILabel
子类化并覆盖intrinsicContentSize
以添加一些额外的空间?感觉a)肮脏,b)鉴于填充没有帮助,这可能无法解决问题吗?
字体本身是这里的问题吗?我可以以某种方式修补字体而不会使字体变得更糟吗?
当我使用较低级别的API时,有什么方法可以修改字体的开头或结尾高度吗?好像我可以继续使用CoreText,因为CTFontCreateCopyWithAttributes(_:_:_:_:)
是一个候选对象,如果我可以仅通过属性修改前导,行距或下降?可以或猴子打补丁/摇动东西而不会在膝盖上向自己开枪吗?我应该只向雷达提交反馈吗?
最佳答案
我知道您在问什么,因为自定义字体也遇到了同样的问题。我将提供两种解决方案。在我自己的项目中,我按照您的建议进行了操作,它覆盖了innerContentSize并为高度和宽度添加了一个填充乘数。就我而言,字体是面向用户的,因此我拥有一个可容纳所有相关信息的结构。 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) {
//hello
guard let labelText = text else { return super.drawText(in: rect) }
//just some breathing room
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的结果:系统
使用字形边界的PaddingUILabel
关于iOS 13 : How can I tweak the leading/descend/line height of a custom font in UIKit/SwiftUI,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63622822/