如何pipe理文本字形边界

假设我有一个时钟应用程序,我想用可以是任意字符集/字体的字符来标记小时。 我想在一个框架中框架字符,并尽可能地填充它。 我怎样才能做到这一点? 如果我使用UILabel ,则在字形周围插入空格。 以下是显示两个标签的示例,两个标签的字体相同但字符不同。 希伯来语数字看起来都比阿拉伯数字短。 有没有办法确定字形的大小或以某种方式推出字形以适应框架?

在这里输入图像说明 在这里输入图像说明

正如你所看到的,希伯来数字虽然被添加到一个更高的UILabel,但是更短。

编辑:自发布以来,我做了第一遍使用核心文本,看看是否可以解决我的问题。 它似乎不会。 请参阅将希伯来字形与阿拉伯数字字形进行比较的插图。 他们黄色是标签界限。 绿色是由核心文本报告的字形矩形。 我希望能得到一个矩形的字形齐平,但它看起来像希伯来字形包括上面和旁边的空间,我希望是字形。 还有什么我应该检查? 希伯来数字 阿拉伯数字

我不知道你使用的是Obj-C还是Swift,但是你可以把它粘贴到Swift Playground页面来查看结果:

次要编辑

 import UIKit import CoreText import PlaygroundSupport class PathView: UIView { var myPath: UIBezierPath? override func draw(_ rect: CGRect) { if let pth = myPath { UIColor.red.setStroke() // glyph path is inverted, so flip vertically let flipY = CGAffineTransform(scaleX: 1, y: -1.0) // glyph path may be offset on the x coord, and by the height (because it's flipped) let translate = CGAffineTransform(translationX: -pth.bounds.origin.x, y: pth.bounds.size.height + pth.bounds.origin.y) // apply the transforms pth.apply(flipY) pth.apply(translate) // stroke the path pth.stroke() // print the modified path for debug / reference print(pth) } } } class TestViewController : UIViewController { override func viewDidLoad() { super.viewDidLoad() // blue background so we can see framing view.backgroundColor = UIColor(red: 0.25, green: 0.5, blue: 01.0, alpha: 1.0) // use a large font so we can see it easily let font = UIFont(name: "Times", size: 160)! // Hebrew character for 8 var unichars = [UniChar]("ח".utf16) unichars = [UniChar]("י".utf16) // init glyphs array var glyphs = [CGGlyph](repeatElement(0, count: unichars.count)) let gotGlyphs = CTFontGetGlyphsForCharacters(font, &unichars, &glyphs, unichars.count) if gotGlyphs { // get the cgPath for the character let cgpath = CTFontCreatePathForGlyph(font, glyphs[0], nil)! // convert it to a UIBezierPath let path = UIBezierPath(cgPath: cgpath) var r = path.bounds // let's show it at 40,40 r = r.offsetBy(dx: 40.0, dy: 40.0) let pView = PathView(frame: r) pView.backgroundColor = .white pView.myPath = path view.addSubview(pView) // print bounds and path data for debug / reference print("bounds of path:", path.bounds) print() print(path) print() } } } let vc = TestViewController() PlaygroundPage.current.liveView = vc 

需要大量的错误检查/处理,但是这可能为您find并使用实际字符字形的边界(而不是标签帧)开了个好头。

结果:

在这里输入图像说明 在这里输入图像说明