如何管理文本字形边界

时间:2017-11-14 16:37:31

标签: ios fonts uilabel glyph

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

enter image description here enter image description here

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

编辑:自发布以来,我首次使用核心文本来查看是否可以解决我的问题。它似乎不会。请参阅这些插图,将希伯来字形与阿拉伯数字字形进行比较。它们是黄色的标签边界。绿色是核心文本报告的字形矩形。我希望得到一个矩形与字形齐平,但看起来希伯来字形包括我预期的字形上方和旁边的空格。还有其他我应该检查的东西吗? Hebrew numeral Arabic numeral

1 个答案:

答案 0 :(得分:1)

我不知道您是否使用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

需要进行大量的错误检查/处理,但这可以为您找到并使用实际字符字形的边界(而不是标签框架)提供良好的开端。

结果:

enter image description here enter image description here