我正在尝试使用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);
但文本不缩小并被截断。 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}}
如果我使用的是实际的绘图方法而不是测量方法,结果是一样的。如果我删除段落样式,它会使文本换行并且不会缩小它。如果我删除段落样式并且我选择仅允许一行文本的大小,则文本也会被截断而不是缩小。怎么了?处理NSStringDrawingContext
的文档或在线资源非常少。我试图避免使用在iOS 7中弃用的sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:
。
答案 0 :(得分:9)
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的这个功能现在没用了。我不知道这是一个错误,还是故意放弃了该功能。
答案 1 :(得分:4)
经过谷歌搜索很长一段时间后,我找不到在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];
答案 2 :(得分:0)
只是想发布这个解决方案,因为我一直在与此争斗几个小时。我永远无法将文本区域缩小,并且总是将最后一行文本切断。
我的解决方案是不添加上下文并将其设置为nil。在查看本网站上的示例时,我得到了这个。 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];
}