【问题标题】:NSString drawInRect:withAttributes: is not drawing text with greater width than the rect in iOS 7.0.3NSString drawInRect:withAttributes: 在 iOS 7.0.3 中绘制的文本宽度不大于矩形
【发布时间】:2015-01-16 08:48:23
【问题描述】:

我正在尝试在我的应用程序中生成一个 pdf。为了绘制一个字符串,我使用 boundingRectWithSize 计算该字符串的边界矩形的大小,然后在该大小的矩形内绘制字符串。

代码在 iOS 7.1 及更高版本中运行良好,但在 iOS 7.0.3 中,如果文本的宽度大于矩形的宽度 (400),则根本不会绘制文本。根据 Apple 的文档,如果字符串不适合矩形,则应该将字符串换行并剪掉,这在 iOS 7.1 及更高版本中发生,但在 iOS 7.0.3 中没有。

这是我的代码 sn-p:

-(void)drawText:(NSString *)string
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);

    NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
 myFontForContentBold, NSFontAttributeName,
 [NSNumber numberWithFloat:1.0], NSBaselineOffsetAttributeName, nil];

    CGRect textRect = [string boundingRectWithSize:CGSizeMake(400, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:attributes context:nil]
textRect = CGRectMake(130, 80, 400, textRect.size.height);

    [string drawInRect:textRect withAttributes:attrsDictionary];
}

我无法弄清楚问题可能是什么。请帮忙。

【问题讨论】:

  • 您的代码可能在以CGRect textRect = ...开头的行有一个错误
  • 我编辑了我的答案。看看它是否有效

标签: ios objective-c ios7 pdf-generation drawinrect


【解决方案1】:

试试这个:

-(void)drawText:(NSString *)string {
// this method must be called after a valid graphic context 
// is configured, it can be called in drawRect:, or a bitmap or pdf context is configured.
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);

    NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                     myFontForContentBold, NSFontAttributeName,
                                     [NSNumber numberWithFloat:1.0], NSBaselineOffsetAttributeName, nil];
    NSAttributedString *richText = [[NSAttributedString alloc] initWithString:string attributes:attrsDictionary];

    CGRect textRect = [richText boundingRectWithSize:CGSizeMake(400, CGFLOAT_MAX)
                                      options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                                      context:nil];

    textRect = CGRectMake(130, 80, 400, textRect.size.height);

    [richText drawInRect:textRect];
}

如果您需要绘制大量文本,请考虑Text Kit

Text Kit 方法:

- (void)drawAddressList:(NSArray *)list atPoint:(CGPoint)point {
    NSTextStorage *textStorage = [[NSTextStorage alloc] init];
    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(400.0f, FLT_MAX)];
    [textStorage addLayoutManager:layoutManager];
    [layoutManager addTextContainer:textContainer];
    textContainer.lineFragmentPadding = 0.0f;

    NSDictionary *attributes = @{NSFontAttributeName:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]};
    // it's a simple attributes for illustration
    for (NSString *address in list) {
        NSString *buffer = [NSString stringWithFormat:@"%@\n", address];
        [textStorage appendAttributedString:[[NSAttributedString alloc] initWithString:buffer attributes:attributes]];
    }

    [layoutManager ensureLayoutForTextContainer:textContainer];
    CGRect rect = [layoutManager usedRectForTextContainer:textContainer];
    rect.size.width = 400.0f;
    rect.size.height = ceilf(rect.size.height);
    rect.origin = point; // this is the frame needed to draw the address list

    [layoutManager drawGlyphsForGlyphRange:NSMakeRange(0, textStorage.length) atPoint:point];
}

【讨论】:

  • 这段代码在哪里调用?您确定图形上下文配置正确吗?您是否在图像中绘制了一些文本?请提供更多背景信息,以便我为您提供帮助。谢谢你。 @Siddesh
  • 我基本上是在尝试打印出可能是多行的地址列表。我在 for 循环中调用此函数,计算每个地址的高度并相应地定位下一个地址。我的问题中写的 x 和 y 值只是任意值。我当前的代码在 iOS 7.1 及更高版本中按预期工作,但在我的一个测试设备(运行 iOS 7.0.3)中,它没有绘制超出我指定宽度 400 的字符串
  • drawRect: 中的 for 循环还是位图上下文?如果它是多行的,我认为Text Kit 的几行代码可能会很好地完成这项工作。因为我没有iOS版本低于iOS 7.1的设备或模拟器,所以无法测试代码。你试过Text Kit吗?
  • for 循环位于一个函数内,该函数通过点击应用程序中的按钮调用。在该函数中,我首先调用UIGraphicsBeginPDFContextToFile(),然后调用UIGraphicsBeginPDFPage(),然后运行我的for 循环,该循环调用我的drawText 函数。我不熟悉 TextKit。感谢您的建议。
  • Text Kit 是一个强大的布局引擎。这只是Text Kit的一个基本应用。如果有兴趣,您可以阅读更多关于它的文档。 @Siddesh
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
相关资源
最近更新 更多