这可能吗?基本上,我有一堆NSAttributedString对象和相应的CTLine对象。我想在drawRect阶段之前获取图像边界。所以在这一点上,没有什么可以吸引的。然后,我将使用这些图像边界来确定我需要为绘图创建的内容。
编辑:另一种尺寸测量可能会很好。但是,调用具有欺骗性名称的CTLineGetTypographicBounds函数只会返回宽度。如果我传入上升和下降浮点的地址,它们会返回零。
编辑:给定的答案在MacOS中运行良好。任何人都可以在iOS中做到吗?答案 0 :(得分:2)
是的,你可以,但不是那么容易。
您应该,通常使用 CTLineGetTypographicBounds(),对我来说,它确实返回 ascent , descent 和 leading ,但有点混乱 - '上升'等于总高度(即应该上升+下降)和'下降'始终是字体的最大下降 - 不管你是否有下降的角色。
其他方法是从行( CTLineGetGlyphRuns )中检索 CTRun (s),然后获取字形数组( CTRunGetGlyphs 或< em> CTRunGetGlyphsPtr )然后使用 CTFontGetBoundingRectsForGlyphs 和 CTFontGetAdvancesForGlyphs 构建您需要的信息。
编辑: 我刚刚找到了这个方法:“ - (NSRect)boundingRectWithSize :( NSSize)大小选项:(NSStringDrawingOptions)选项” NSAttributedString 它似乎完全 需要什么。
希望,这很有帮助......
答案 1 :(得分:2)
CTLineGetTypographicBounds()
返回的边界与图像边界不同。正如名称(和Иван的回答)所暗示的那样,为字体定义了上升等,并且不会根据字符串进行更改。例如,如果要在多行文本中找到正确的行高,则可以使用它,因为行高通常不应取决于您使用的确切字符。
CTLineGetImageBounds()
返回完全适合图像的边界。例如,如果要围绕一行绘制一个框,则这就是您所需要的。
CTLineGetImageBounds()
需要一个上下文,因为可能有文本转换和类似的东西。如果您不想担心这一点,只需使用虚拟上下文。例如:
CTLineRef line;
// create the line...
UIGraphicsBeginImageContext(CGSizeMake(1, 1));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextPosition(context, 0, 0);
CGRect bounds = CTLineGetImageBounds(line, context);
UIGraphicsEndImageContext();
// use bounds...
答案 2 :(得分:2)
如果您正在为iOS6 +开发。您可以使用以下方法:
CTLineRef line;
// Create the line...
CGRect bounds = CTLineGetBoundsWithOptions(line, kCTLineBoundsUseGlyphPathBounds);
// use bounds...
假设您在上下文中没有应用变换,但不需要上下文,则此变量与CTLineGetImageBounds()
具有相同的边界。对于iOS 5及更低版本,您需要使用Иван描述的方法。
CTLineGetTypographicBounds()
给出了与此函数或图像边界不同的宽度。我不知道为什么。返回的上升和下降是字体,而不是CTLineRef.
答案 3 :(得分:0)
另一种方法是使用CTFontGetGlyphsForCharacters()
将字符串转换为字形,然后使用从第一个函数获得的字形数组调用CTFontGetBoundingRectsForGlyphs()
。后一个函数返回“字形运行的整个边界矩形”,因此不必担心必须对各个边界值进行处理。如果在iOS中成功使用这两个功能。
如果这样做,请记住字形和字符之间的映射并不总是一对一,尤其是当字符串包含非英文字符时。