如何使NSStringDrawingContext缩小文本?

我试图使用iOS 6的属性stringAPI来计算文本的大小,并在必要时缩小字体大小。 但是,我不能像文档所说的那样工作。

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); 

但文本不缩水,被截断。 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}} 

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

NSStringDrawingContext的minimumScaleFactor在iOS 7中看起来坏了。

据我所知,即使在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]; } 

在iOS 6中, scale大约是0.85,您可以使用它来缩小文本。 但是在iOS 7中, scale保持为1,表明没有收缩现象,NSStringDrawingContext的这个特性现在是无用的。 我不知道这是一个错误,还是故意放弃这个function。

谷歌长时间search后,我没有find一个解决scheme在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]; 

只是想发布这个解决scheme,因为我一直在与这个战斗了几个小时。 我永远不可能让文本区域缩小,并始终将文本的最后一行切断。

对我来说,解决scheme是不添加上下文,只需将其设置为零。 当看到这个网站的例子时,我得到了这个。 https://littlebitesofcocoa.com/144-drawing-multiline-strings

获取大小后,请注意框使用

 pageStringSize = [myString boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrsDictionary context:nil]; 

我仍然需要通过手动缩放字体来循环:

 while (pageStringSize.size.height > 140 && scale > 0.5) { scale = scale - 0.1; font = [UIFont fontWithName:@"Chalkboard SE" size:24.0 *scale]; attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName,[NSNumber numberWithFloat:1.0], NSBaselineOffsetAttributeName, nil]; pageStringSize = [myString boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrsDictionary context:nil]; }