CTFrame有时是空的,具体取决于UIFont pointSize

问题描述 投票:0回答:1

我正在尝试使用Core Text在CGContext中绘制一个属性字符串。我有一个有趣的问题,它适用于某些字体大小但不适用于其他字体。 CTFrame有时是空的 - visible string range = (0,0) - 这意味着框架设置无法布局文本。我发现这是因为路径太小而无法在其中绘制文本。如果我在这种情况下将高度加10,那么它就可以了。

任何想法为什么会这样?我怎样才能得到它需要的尺寸,不小而不大?

let fontSize: CGFloat = 191 //FIXME: 190 and 192 work, why not 191?
let attributedString = NSAttributedString(string: "Hello", attributes: [.font: UIFont.systemFont(ofSize: fontSize)])
let textSize = attributedString.size()

let rect = CGRect(origin: .zero, size: CGSize(width: 4000, height: 3000))
let positionX = rect.width - ceil(textSize.width) //right edge of rect
let path = CGPath(rect: CGRect(x: positionX, y: 0, width: ceil(textSize.width), height: ceil(textSize.height)/* + 10*/), transform: nil)

let framesetter = CTFramesetterCreateWithAttributedString(attributedString)
let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributedString.length), path, nil)
print(frame)

fontSize == 190的结果:

<CTFrame: 0x600000598a80>{visible string range = (0, 5), path = <CGPath 0x600001f8fc50>, attributes = (null), lines = (
    "<CTLine: 0x60000039a670>{run count = 1, string range = (0, 5), width = 408.574, A/D/L = 180.908/45.8301/0, glyph count = 5, runs = (\n\n<CTRun: 0x7fdde391adf0>{string range = (0, 5), string = \"Hello\", attributes = {\n    NSFont = \"<UICTFont: 0x7fdde1c0fc20> font-family: \\\".SFUIDisplay\\\"; font-weight: normal; font-style: normal; font-size: 190.00pt\";\n}}\n\n)\n}"
)}

fontSize == 191的结果:

<CTFrame: 0x600003e56bc0>{visible string range = (0, 0), path = <CGPath 0x60000240f0c0>, attributes = (null), lines = (
)}
ios nsattributedstring core-text
1个回答
0
投票

接听电话,对格式化问题感到抱歉。使用CTFramesetterSuggestFrameSizeWithConstraints代替代码中的textSize。

 let attri = NSAttributedString(string: str, attributes: self.attributes(str: str, font: ft))
 let frameSetter = CTFramesetterCreateWithAttributedString((attri as CFAttributedString))
 var fitRange = CFRangeMake(0, 0)
 var fitRange = CFRangeMake(0, 0)
 let suggested = CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, CFRangeMake(0,attri.length), nil, CGSize(width:bounds.width,height:.greatestFiniteMagnitude), &fitRange)
 path.addRect(CGRect(x: 0, y: 0, width: ceil(max(suggested.width, self.bounds.width)), height: ceil(max(suggested.height, self.bounds.height))))
 let ctFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0,attri.length), path, nil)

© www.soinside.com 2019 - 2024. All rights reserved.