2012-12-01 14 views
18

標準のUILabelを使用して、垂直方向のスペースを埋めるようにフォントサイズを増やしたいと考えています。このquestionのための受け入れ答えからインスピレーションを取って、私はこののdrawRect実装にUILabelのサブクラスを定義した:UILabelに垂直にフィットするフォントサイズを調整する

- (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(w x h)のラベル、Helveticaをフォントとして使用し、ラベルにうまく収まる60の開始点サイズで開始しました。

uilabel

uilabel subclass

私は、フォントのディセンダとアセンダを見てきましたが、中にこれらを考慮しスケーリングを試してみました:ここに文字列「{水銀」を使用して標準UILabelと私のサブクラスからの出力例です異なる組み合わせが、まだ運がなかった。任意のアイデアは、これは、ディセンダとアセンダの長さが異なるフォントを使用することですか?

答えて

12

pointsPerPixelのためのあなたの計算がアップ間違った方法であるとき、フレームサイズのフォントを変更する必要がある唯一の時間があるとして、それは...

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

また、多分このコードはlayoutSubviewsにする必要がありますする必要があります変更。

+1

まあ...それは恥ずかしいほど単純な間違いだった。それを見つけていただきありがとうございます。 – user524261

+0

私は 'layoutSubviews'でそれを実装しようとしましたが、うまくいくとは思いません。その理由は、 'UILabel'サブクラスに新しいフォントを割り当てると' layoutSubviews'が呼び出されてしまうという問題があると思います。私の実装では、私のアプリケーションの待ち行列の1つがロックアップされました。 – user444731

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のフォントに至るまで、私がテストしたすべてのサイズのラベルのボックス内に収まる:ちょうど徹底のために、ここで私がテストしたサンプルコードです。私は計算を逆にしたとき、同じ結果を見ましたが、フォントが大きすぎます。

+0

float pointSize値を使用しているため、整数への丸めはありません。そうであっても、fontSizeは全体のポイントサイズを超えています。ファクタで元に戻すことに同意しましたが、これは正確な計算よりもファッジのほうが多く、フォントによって異なります。 – user524261

関連する問題