19

我想采用标准的 UILabel 并增加字体大小以填充垂直空间。从这个问题的公认答案中汲取灵感,我在 UILabel 上使用这个 drawRect 实现定义了一个子类:

- (void)drawRect:(CGRect)rect
{
    // Size required to render string
    CGSize size = [self.text sizeWithFont:self.font];

    // For current font point size, calculate points per pixel
    float pointsPerPixel = size.height / self.font.pointSize;

    // Scale up point size for the height of the label
    float desiredPointSize = rect.size.height * pointsPerPixel;

    // Create and assign new UIFont with desired point Size
    UIFont *newFont = [UIFont fontWithName:self.font.fontName size:desiredPointSize];
    self.font = newFont;

    // Call super
    [super drawRect:rect];
}

但这不起作用,因为它会将字体缩放到标签底部之外。如果你想复制它,我从标签 289x122 (wxh) 开始,字体为 Helvetica,起始点大小为 60,适合标签。这是使用字符串“{Hg”的标准 UILabel 和我的子类的示例输出:

uilabel

uilabel 子类

我已经查看了字体下降和上升,尝试缩放以不同的组合考虑这些,但仍然没有任何运气。任何想法,这与具有不同下降和上升长度的不同字体有关吗?

4

2 回答 2

13

你的计算pointsPerPixel方法不对,应该是...

float pointsPerPixel =  self.font.pointSize / size.height;

另外,也许这段代码应该在,layoutSubviews因为字体应该改变的唯一时间是帧大小改变的时候。

于 2012-12-02T17:43:46.510 回答
0

我想知道它是否是一个四舍五入的错误,它会逐渐增大到下一个更大的字体大小。你能稍微缩放一下rec.size.height吗?就像是:

float desiredPointSize = rect.size.height *.90 * pointsPerPixel;

更新:您的 pointPerPixel 计算是倒退的。你实际上是用字体点来划分像素,而不是用像素来划分点。交换这些,它每次都有效。只是为了彻底,这是我测试的示例代码:

//text to render    
NSString *soString = [NSString stringWithFormat:@"{Hg"];
UIFont *soFont = [UIFont fontWithName:@"Helvetica" size:12];

//box to render in
CGRect rect = soLabel.frame;

//calculate number of pixels used vertically for a given point size. 
//We assume that pixel-to-point ratio remains constant.
CGSize size = [soString sizeWithFont:soFont];
float pointsPerPixel;
pointsPerPixel = soFont.pointSize / size.height;   //this calc works
//pointsPerPixel = size.height / soFont.pointSize; //this calc does not work

//now calc which fontsize fits in the label
float desiredPointSize = rect.size.height * pointsPerPixel;
UIFont *newFont = [UIFont fontWithName:@"Helvetica" size:desiredPointSize];

//and update the display
[soLabel setFont:newFont];
soLabel.text = soString;

对于我测试的每种尺寸(从 40pt 到 60pt 字体),它都可以缩放并适合标签框。当我颠倒计算时,我看到了相同的结果,字体太高,不适合盒子。

于 2012-12-02T08:13:56.867 回答