假设我有一个时钟应用程序,我想用可能是任意字符集/字体的字符标记小时。我想在一个框架中构造字符并尽可能地填充它。我怎样才能做到这一点?如果我使用UILabel
,则会在字形周围插入空格。以下是显示两个标签的示例,两个标签具有相同的字体但具有不同的字符。希伯来语数字看起来都比阿拉伯数字短。有没有办法确定字形的大小或以某种方式推出字形以适应框架?
正如你所看到的,希伯来语数字虽然被添加到更高的UILabel中,但它更短。
编辑:自发布以来,我首次使用核心文本来查看是否可以解决我的问题。它似乎不会。请参阅这些插图,将希伯来字形与阿拉伯数字字形进行比较。它们是黄色的标签边界。绿色是核心文本报告的字形矩形。我希望得到一个矩形与字形齐平,但看起来希伯来字形包括我预期的字形上方和旁边的空格。还有其他我应该检查的东西吗?
答案 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
需要进行大量的错误检查/处理,但这可以为您找到并使用实际字符字形的边界(而不是标签框架)提供良好的开端。
结果: