我在iOS7中已弃用了许多用于确定用于创建复杂pdf文档的打印字符串布局的方法。文档调用相同的方法来替换所有不推荐使用的sizeWithFont方法:
boundingRectWithSize:options:attributes:
这对于sizeWithFont:ConstrainedTosize:lineBreakMode
来说没什么问题,但如果我只想让我的字符串在一行上呢?我不知道如何使用最大高度,所以我没有一个矩形作为第一个参数的值移交。
这是我限制到给定大小时所拥有的。
CGFloat maxHeightAllowable = _maxHeight;
CGSize issueTitleMaxSize = CGSizeMake(_issueListTitleColWidth - (kColumnMargin *2), maxHeightAllowable);
NSDictionary *issueTitleAttributes = [NSDictionary dictionaryWithObjectsAndKeys:_bodyFont, NSFontAttributeName, nil];
CGRect issueTitleRect = CGRectIntegral([issueTitleText boundingRectWithSize:issueTitleMaxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:issueTitleAttributes context:nil]);
CGSize issueTitleSize = issueTitleRect.size;
如果我不知道maxHeight,或者实际上,一行的高度正是我想要找到的,我将如何使用相同的方法?
我明白为什么他们正在推动NSAttributed字符串和自动布局的兼容性,但为什么要弃用这些呢?在我的情况下,替换现在需要4或5个步骤,过去曾经是1或2。
根据T先生的建议,使用font的lineHeight属性,我将这些方法放在一个类别中,大大简化了我的替换。
#import "NSString+SizingForPDF.h"
@implementation NSString (SizingForPDF)
-(CGSize)integralSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)maxSize
{
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
CGRect rect = CGRectIntegral([self boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:attributes context:nil]);
return rect.size;
}
-(CGSize)integralSizeWithFont:(UIFont *)font maxWidth:(CGFloat)maxWidth numberOfLines:(NSInteger)lines
{
if (lines == 0) {
lines = 1;
}
NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
CGFloat height = font.lineHeight * lines;
CGSize maxsize = CGSizeMake(maxWidth, height);
CGRect rect = CGRectIntegral([self boundingRectWithSize:maxsize options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading attributes:attributes context:nil]);
return rect.size;
}
@end
答案 0 :(得分:15)
如果你只想找到一行的高度,你不能只使用你的字体的lineHeight
属性吗?我用它来设置标签的高度或正确预测元素的高度而没有任何问题。我不确定pdf文件在这方面是否有所不同。
此外,我相信这些函数已被弃用,因为NSString + UIKit函数(sizeWithFont:...
等)系列基于UIStringDrawing库,它不是线程安全的。如果您尝试不在主线程上运行它们(就像任何其他UIKit功能一样),您将获得不可预测的行为。特别是,如果您同时在多个线程上运行该函数,它可能会使您的应用程序崩溃。这就是为什么在iOS 6中,他们为NSAttributedStrings引入了boundingRectWithSize:...
方法。它建立在NSStringDrawing库之上,并且是线程安全的。
就此而言,如果您只支持iOS 6和iOS 7,那么我肯定会将所有NSString的sizeWithFont:...
更改为NSAttributeString的boundingRectWithSize
。如果您碰巧有一个奇怪的多线程角落案例,它会为您省去很多麻烦!这是我如何转换NSString的sizeWithFont:constrainedToSize:
:
过去是什么:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font
constrainedToSize:(CGSize){width, CGFLOAT_MAX}];
可以轻松替换为:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
[[NSAttributedString alloc]
initWithString:text
attributes:@
{
NSFontAttributeName: font
}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
请注意文档提及:
在iOS 7及更高版本中,此方法返回小数(大小) 返回的CGRect的组件);使用返回的大小来确定大小 视图,必须使用将其值提高到最接近的更高整数 使用ceil函数。
因此,要拉出用于调整视图大小的计算高度或宽度,我会使用:
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);