为什么使用 UIFont preferredFontForTextStyle 时 boundingRectWithSize 错误?
Why is boundingRectWithSize wrong when using UIFont preferredFontForTextStyle?
我发现对 boundingRectWithSize
的调用是极其不正确的,当使用 NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody]
调用时,缺少一整行。不过用[UIFont fontWithName:@"Helvetica Neue" size:17.f]
这个字体就好了。
这是显示错误的测试代码:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *measureText = @"I'm the king of Portmanteaus ... My students slow clap";
CGSize maxSize = CGSizeMake(226.f, CGFLOAT_MAX);
UIFont *targetFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
CGRect stringRect = [measureText boundingRectWithSize:maxSize
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:@{ NSFontAttributeName : targetFont }
context:nil];
UILabel *drawLabel = [[UILabel alloc] initWithFrame:stringRect];
drawLabel.font = targetFont;
[self.view addSubview:drawLabel];
drawLabel.textColor = [UIColor blackColor];
drawLabel.text = measureText;
drawLabel.numberOfLines = 0;
}
输出:
但是,如果我targetFont = [UIFont fontWithName:@"Helvetica Neue" size:17.f];
正确呈现:
在第一种情况下,大小为 {226.20200000000008, 42.281000000000006},但在正确的第二种情况下,大小为 {228.64999999999998, 60.366999999999997}。因此,这不是一个四舍五入的问题;这缺少一个全新的行。
将 [UIFont preferredFontForTextStyle:UIFontTextStyleBody]
作为参数传递给 boundingRectWithSize
是错误的吗?
编辑
根据下面答案中的评论,我认为 iOS 如何处理与前一个词相关的三个句点存在错误。我添加了这段代码:
measureText = [measureText stringByReplacingOccurrencesOfString:@" ..." withString:@"…"];
并且它工作正常。
标签在文本的外侧添加了一点边距,而您不允许这样做。
相反,如果您使用的自定义 UIView 的大小与字符串矩形的大小完全相同,您会发现文本非常适合:
这是我使用的代码。在视图控制器中:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *measureText = @"I'm the king of Portmanteaus ... My students slow clap";
CGSize maxSize = CGSizeMake(226.f, CGFLOAT_MAX);
UIFont *targetFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
CGRect stringRect = [measureText boundingRectWithSize:maxSize
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:@{ NSFontAttributeName : targetFont }
context:nil];
stringRect.origin = CGPointMake(100,100);
StringDrawer* sd = [[StringDrawer alloc] initWithFrame:stringRect];
[self.view addSubview:sd];
[sd draw:[[NSAttributedString alloc] initWithString:measureText attributes:@{ NSFontAttributeName : targetFont }]];
}
这里是 String Drawer(一个 UIView 子类):
@interface StringDrawer()
@property (nonatomic, copy) NSAttributedString* text;
@end
@implementation StringDrawer
- (instancetype) initWithFrame: (CGRect) frame {
self = [super initWithFrame:frame];
self.backgroundColor = [UIColor yellowColor];
return self;
}
- (void) draw: (NSAttributedString*) text {
self.text = text;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
[self.text drawInRect:rect];
}
@end
此外,如果您的目的是通过调整其高度来制作包含文本的标签,为什么不让自动布局完成它的工作呢?下一个屏幕截图是一个 UILabel,宽度限制为 226,没有高度限制。我已经用代码为它分配了你的字体和文本。如您所见,它已调整自身大小以容纳所有文本:
这是通过这段代码实现的,不需要更多:
NSString *measureText = @"I'm the king of Portmanteaus ... My students slow clap";
UIFont *targetFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
self.lab.font = targetFont;
self.lab.text = measureText;
我发现对 boundingRectWithSize
的调用是极其不正确的,当使用 NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody]
调用时,缺少一整行。不过用[UIFont fontWithName:@"Helvetica Neue" size:17.f]
这个字体就好了。
这是显示错误的测试代码:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *measureText = @"I'm the king of Portmanteaus ... My students slow clap";
CGSize maxSize = CGSizeMake(226.f, CGFLOAT_MAX);
UIFont *targetFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
CGRect stringRect = [measureText boundingRectWithSize:maxSize
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:@{ NSFontAttributeName : targetFont }
context:nil];
UILabel *drawLabel = [[UILabel alloc] initWithFrame:stringRect];
drawLabel.font = targetFont;
[self.view addSubview:drawLabel];
drawLabel.textColor = [UIColor blackColor];
drawLabel.text = measureText;
drawLabel.numberOfLines = 0;
}
输出:
但是,如果我targetFont = [UIFont fontWithName:@"Helvetica Neue" size:17.f];
正确呈现:
在第一种情况下,大小为 {226.20200000000008, 42.281000000000006},但在正确的第二种情况下,大小为 {228.64999999999998, 60.366999999999997}。因此,这不是一个四舍五入的问题;这缺少一个全新的行。
将 [UIFont preferredFontForTextStyle:UIFontTextStyleBody]
作为参数传递给 boundingRectWithSize
是错误的吗?
编辑
根据下面答案中的评论,我认为 iOS 如何处理与前一个词相关的三个句点存在错误。我添加了这段代码:
measureText = [measureText stringByReplacingOccurrencesOfString:@" ..." withString:@"…"];
并且它工作正常。
标签在文本的外侧添加了一点边距,而您不允许这样做。
相反,如果您使用的自定义 UIView 的大小与字符串矩形的大小完全相同,您会发现文本非常适合:
这是我使用的代码。在视图控制器中:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *measureText = @"I'm the king of Portmanteaus ... My students slow clap";
CGSize maxSize = CGSizeMake(226.f, CGFLOAT_MAX);
UIFont *targetFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
CGRect stringRect = [measureText boundingRectWithSize:maxSize
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:@{ NSFontAttributeName : targetFont }
context:nil];
stringRect.origin = CGPointMake(100,100);
StringDrawer* sd = [[StringDrawer alloc] initWithFrame:stringRect];
[self.view addSubview:sd];
[sd draw:[[NSAttributedString alloc] initWithString:measureText attributes:@{ NSFontAttributeName : targetFont }]];
}
这里是 String Drawer(一个 UIView 子类):
@interface StringDrawer()
@property (nonatomic, copy) NSAttributedString* text;
@end
@implementation StringDrawer
- (instancetype) initWithFrame: (CGRect) frame {
self = [super initWithFrame:frame];
self.backgroundColor = [UIColor yellowColor];
return self;
}
- (void) draw: (NSAttributedString*) text {
self.text = text;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
[self.text drawInRect:rect];
}
@end
此外,如果您的目的是通过调整其高度来制作包含文本的标签,为什么不让自动布局完成它的工作呢?下一个屏幕截图是一个 UILabel,宽度限制为 226,没有高度限制。我已经用代码为它分配了你的字体和文本。如您所见,它已调整自身大小以容纳所有文本:
这是通过这段代码实现的,不需要更多:
NSString *measureText = @"I'm the king of Portmanteaus ... My students slow clap";
UIFont *targetFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
self.lab.font = targetFont;
self.lab.text = measureText;