我正在尝试使用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 = (
)}

最佳答案

通过电话接听,因此对格式问题感到抱歉。使用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)









关于ios - CTFrame有时为空,具体取决于UIFont pointSize,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54914472/

10-10 23:25