如何在视图中绘制没有边距的字符串?

Luk*_*uke 9 string uikit uiview nsattributedstring ios

我无法NSAttributedString在视图中绘制一个没有边距的东西.这是我的代码:

NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:72.0f]};
NSAttributedString *string = [[NSAttributedString alloc] initWithString:@"Hello"
                                                             attributes:attributes];
[string drawWithRect:rect
             options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesDeviceMetrics
             context:nil];
Run Code Online (Sandbox Code Playgroud)

这会导致以下行为:

用边距绘制的字符串

请注意左侧和顶部的边距.

  1. 如何避免这些边距并使文本完全符合包含视图的边缘?我想要的是实际绘制的文本与视图的边缘相交,也就是说,在任何字形中绘制的最顶部像素应该在视图的顶部,并且在任何字形中绘制的最左边的像素位于视图的左侧.风景.
  2. 假设1是可能的,有没有办法可以得到绘制文本的实际宽度和高度,这样我就可以计算字体大小和字距以使文本符合底部和右边缘?

我意识到可能有一些方法来对齐文本而不使其符合视图的边缘,但是使其符合视图的边缘将允许我使用自动布局等直观地使用视图.

当字符串包含前导或尾随空格时,我不关心行为.

如果无法做到这一点NSAttributedString,是否有其他方法可以获得您建议的此行为?

澄清一下,这是我想要的第一号.

期望的行为

小智 5

您可以使用CoreText获取高度,宽度向量值:

double fWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
size_t width = (size_t)ceilf(fWidth);
size_t height = (size_t)ceilf(ascent + descent + leading);
Run Code Online (Sandbox Code Playgroud)

所以你可以得到直肠.但最高利润没有错


Joe*_*ith 2

使用 CoreText,CTLineGetTypgraphicBounds() 可能就是您正在寻找的。我自己没用过这个。以下代码演示了这个想法(将“Hello”绘制到没有上/左边距的自定义 UIView)。

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()
    UIGraphicsPushContext(context)

    let viewHeight = bounds.size.height

    let attributedString = NSAttributedString(string: "Hello")
    let line = CTLineCreateWithAttributedString(attributedString)
    var ascent: CGFloat = 0.0
    let width = CTLineGetTypographicBounds(line, &ascent, nil, nil)

    CGContextSaveGState(context)

    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextTranslateCTM(context, 0, -viewHeight)
    CGContextSetTextPosition(context, 0, viewHeight - ascent)
    CTLineDraw(line, context)

    CGContextRestoreGState(context)

    UIGraphicsPopContext()
}
Run Code Online (Sandbox Code Playgroud)