【问题标题】:Bounding Rectangle using Core Text使用核心文本边界矩形
【发布时间】:2014-01-03 11:11:10
【问题描述】:

如果我错了,请纠正我。

我尝试使用 Core Text 计算出字符的确切边界矩形。但是我收到的高度总是大于屏幕上绘制字符的实际高度。在这种情况下,实际高度在 20 左右,但无论如何函数只给我 46。

有人能解释一下吗?

谢谢。

这里是代码

- (void)viewDidLoad{
    [super viewDidLoad];
    NSString *testString = @"A";
    NSAttributedString *textString =  [[NSAttributedString alloc] initWithString:testString attributes:@{
                                                                                                            NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:40]
                                                                                                            }];
    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:textString];
    NSLayoutManager *textLayout = [[NSLayoutManager alloc] init];
    // Add layout manager to text storage object
    [textStorage addLayoutManager:textLayout];
    // Create a text container
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.view.bounds.size];
    // Add text container to text layout manager
    [textLayout addTextContainer:textContainer];

    NSRange range = NSMakeRange (0, testString.length);

    CGRect boundingBox = [textLayout boundingRectForGlyphRange:range inTextContainer:textContainer];

    //BoundingBox:{{5, 0}, {26.679688, 46}}
    // Instantiate UITextView object using the text container
    UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(20,20,self.view.bounds.size.width-20,self.view.bounds.size.height-20)
                                      textContainer:textContainer];
    // Add text view to the main view of the view controler

    [self.view addSubview:textView];
}

【问题讨论】:

  • 抱歉,您是说这在 viewDidLoad 中有效吗?不工作时它在哪里?
  • 抱歉,刚刚意识到这已经很老了......这仍然是一个问题吗?
  • @GeorgeGreen 嗨,乔治,是的,这对我来说仍然是个问题。我已经编辑了问题以使其更清楚。我的意思是代码可以粘贴到viewDidLoad中进行测试。谢谢
  • 对于段落样式,我使用 para.boundingRectWithSize(CGSizeMake(fontBoxWidth,10000), options: options, context: nil) 和 CTLines 我使用 CTLineGetTypographicBounds 和 CTFrameGetLineOrigins 来计算边界框

标签: ios uitextview core-text bounding-box nslayoutmanager


【解决方案1】:

我目前正在为 Core Text 渲染进行此工作,但很惊讶没有直接提供此类信息(用于相关图形,例如适合的背景/轮廓)

这些都是从其他 stackoverflow 问题和我自己的测试中进行的工作以获得完美的边界框(紧密)

常用字体属性

    let leading = floor( CTFontGetLeading(fontCT) + 0.5)
    let ascent = floor( CTFontGetAscent(fontCT) + 0.5)
    let descent = floor( CTFontGetDescent(fontCT) + 0.5)
    var lineHeight = ascent + descent + leading
    var ascenderDelta = CGFloat(0)
    if leading > 0 {
        ascenderDelta = 0
    }
    else {
        ascenderDelta = floor( 0.2 * lineHeight + 0.5 )
    }
    lineHeight = lineHeight + ascenderDelta

段落样式

    var para = NSMutableAttributedString()
    // append attributed strings and set NSMutableParagraphStyle
    /* ... */
    let options : NSStringDrawingOptions = .UsesFontLeading | .UsesLineFragmentOrigin | .UsesDeviceMetrics
    let rect = para.boundingRectWithSize(CGSizeMake(fontBoxWidth,10000), options:  options, context: nil)
    var backgroundBounds = CGRectMake(boundingBox.origin.x + point.x, boundingBox.origin.y + point.y + lineHeight, boundingBox.width, boundingBox.height + ascenderDelta)

对于 CTFrames

    let lines = CTFrameGetLines(frame) as NSArray
    let numLines = CFArrayGetCount(lines)

    for var index = 0; index < numLines; index++ {
        var ascent = CGFloat(0),
        descent = CGFloat(0),
        leading = CGFloat(0),
        width = CGFloat(0)
        let line = lines[index] as! CTLine
        width = CGFloat(CTLineGetTypographicBounds(line, &ascent,  &descent, &leading))
        // adjust with common font property code
        var  lineOrigin : CGPoint = CGPointMake(0,0)
        CTFrameGetLineOrigins(frame, CFRangeMake(index, 1), &lineOrigin)
        let bounds = CGRectMake(point.x + lineOrigin.x, point.y + lineOrigin.y - descent, width, ascent + descent)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多