如何使NSStringDrawingContext缩小文本?

Gui*_*ume 14 text nsattributedstring ios

我正在尝试使用iOS 6的属性字符串API来计算文本的大小,并在必要时缩小字体大小.但是,正如文档所说,我无法让它工作.

NSString *string = @"This is a long text that doesn't shrink as it should";

NSStringDrawingContext *context = [NSStringDrawingContext new];
context.minimumScaleFactor = 0.5;

UIFont *font = [UIFont fontWithName:@"SourceSansPro-Bold" size:32.f];

NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.lineBreakMode = NSLineBreakByClipping;

NSDictionary *attributes = @{ NSFontAttributeName: font,
                              NSParagraphStyleAttributeName: paragraphStyle };

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:self.title attributes:attributes];

CGRect rect = [attributedString boundingRectWithSize:CGSizeMake(512.f, 512.f) options:NSStringDrawingUsesLineFragmentOrigin context:context];

NSLog(@"rect: %@, context: %@", NSStringFromCGRect(rect), context.debugDescription);
Run Code Online (Sandbox Code Playgroud)

但是文本没有缩小并被截断.actualScaleFactor永远1.日志结果如下:

rect:{{0, 0}, {431.64801, 80.447998}}, context:<NSStringDrawingContext: 0x14e85770> minimumScaleFactor:0.500000 minimumTrackingAdjustment:0.000000 actualScaleFactor:1.000000 actualTrackingAdjustment:0.000000 totalBounds:{{0, 0}, {431.64801, 80.447998}}
Run Code Online (Sandbox Code Playgroud)

如果我使用实际绘图方法而不是测量方法,结果是相同的.如果我删除段落样式,它会使文本换行并且不会缩小它.如果我删除段落样式并且我选择仅允许一行文本的大小,则文本也会被截断而不是缩小.怎么了?很少有文档或在线资源处理NSStringDrawingContext.而我正试图避免sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:在iOS 7中弃用它.

mat*_*att 9

minimumScaleFactor在iOS 7中,NSStringDrawingContext 似乎已破裂.

据我所知,即使在iOS 6中,它也不适用于绘图; 它的工作进行测量,这样你就可以制定出在这背景下,会发生什么工作图纸,像一个UILabel.这样,您就知道标签的正确最小高度.

或者,您可以使用生成的比例因子自行缩小文本,以了解现在适合的文本.

例:

- (void)drawRect:(CGRect)rect
{
    // rect is 0,0,210,31

    NSMutableAttributedString* s = 
        [[NSMutableAttributedString alloc] initWithString: @"This is the army Mister Jones."];
    [s addAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"GillSans" size:20]} 
        range:NSMakeRange(0,s.length)];

    NSMutableParagraphStyle* para = [[NSMutableParagraphStyle alloc] init];
    para.lineBreakMode = NSLineBreakByTruncatingTail;
    [s addAttributes:@{NSParagraphStyleAttributeName:para} 
        range:NSMakeRange(0,s.length)];

    NSStringDrawingContext* con = [[NSStringDrawingContext alloc] init];
    con.minimumScaleFactor = 0.5;

    CGRect result = 
        [s boundingRectWithSize:rect.size 
            options:NSStringDrawingUsesLineFragmentOrigin context:con];
    CGFloat scale = con.actualScaleFactor;
    // ...(could have a check here to see if result fits in target rect)...

    // fix font to use scale factor, and draw
    [s addAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"GillSans" size:20*scale]} 
        range:NSMakeRange(0,s.length)];
    [s drawWithRect:rect options:NSStringDrawingUsesLineFragmentOrigin context:nil];

}
Run Code Online (Sandbox Code Playgroud)

在iOS 6中,scale大约是0.85,您可以使用它来缩小文本.但是在iOS 7中,scale仍然保持在1,表明没有收缩,NSStringDrawingContext的这个功能现在没用了.我不知道这是一个错误还是故意放弃了这个功能.

  • @Andy你读过我说的话吗?它坏了.破碎.它不起作用.亲自尝试一下.这就是我向OP展示可能的解决方法的原因.解决方法适用于破碎的事情.你知道,错误.如果可以将上下文传递给`drawWithRect:`,OP就不会问这个问题而我也不会回答它. (3认同)

Shi*_*goo 5

谷歌搜索了很长时间之后,我没有找到在iOS7下运行的解决方案。现在,我知道这非常丑陋,所以使用以下解决方法。我在内存中渲染一个UILabel,截图并绘制。UILabel能够正确缩小文本。

但是也许有人觉得它有用。

    UILabel *myLabel = [[UILabel alloc] initWithFrame:myLabelFrame];
    myLabel.font = [UIFont fontWithName:@"HelveticaNeue-BoldItalic" size:16];
    myLabel.text = @"Some text that is too long";
    myLabel.minimumScaleFactor = 0.5;
    myLabel.adjustsFontSizeToFitWidth = YES;
    myLabel.backgroundColor = [UIColor clearColor];

    UIGraphicsBeginImageContextWithOptions(myLabelFrame.size, NO, 0.0f);
    [[myLabel layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [screenshot drawInRect:myLabel.frame];
Run Code Online (Sandbox Code Playgroud)