【问题标题】:Why is boundingRectWithSize wrong when using UIFont preferredFontForTextStyle?为什么使用 UIFont preferredFontForTextStyle 时 boundingRectWithSize 错误?
【发布时间】:2015-09-03 13:12:47
【问题描述】:

我发现使用NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody] 调用时,调用boundingRectWithSize 是非常不正确的,缺少一整行。但是,使用[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 是错误的吗?


编辑

根据下面答案中的 cmets,我认为 iOS 如何处理与后续单词相关的三个句点存在错误。我已添加此代码:

measureText = [measureText stringByReplacingOccurrencesOfString:@" ..." withString:@"…"];

它可以正常工作。

【问题讨论】:

    标签: ios8 nsstring uilabel uifont


    【解决方案1】:

    标签会在文本外部添加一点边距,而您不允许这样做。

    如果您使用与字符串 rect 大小完全一致的自定义 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;
    

    【讨论】:

    • 另外我认为"..." 正在造成麻烦,在某种程度上我不能完全确定。如果将其更改为省略号字符或“xxx”,则会得到预期的结果。
    • 另外,您不允许 UILabel 不应具​​有非整数大小这一事实。我们应该对矩形进行整数化...
    • 这对我来说似乎不对 - 据我所知,在 UILabel 上没有公布的边距,如果我需要,我不应该放弃对 UIView + drawInRect 使用 UILabel能够适当地调整它的大小。在 iOS 上使用 boundingRectWithSize + UILabel 不是很常见的设计模式吗?另外 - 问题是它没有给我的文本第三行,所以即使四舍五入也不会有所作为。 IDK 为什么您的示例仅适用于 2 行......
    • 我对我的回答也不完全满意。不过,我已经证明了 something:我已经证明给定的文本确实适合它所说的矩形大小。
    • 但我还是觉得你的做法很奇怪。我们有自动布局,那么为什么不使用它并让标签设置自己的高度呢?我已将其添加到我的答案中;如您所见,它工作得很好——我们得到一个给定宽度的标签,它会自动完全适应文本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多