2013-11-28 10 views
21

2つのUILabelが横に並んでいて、左右に調整されているので、以下のようになります。AutoLayout 2つのUILabelsが同じフォントサイズを持つようにする

|-Some text left adjusted----------some other text right adjusted-| 

どちらのラベルがYES adjustsFontSizeToFitWidth =を持っているし、ための十分なスペースがない場合、彼らは、彼らができるだけ多くのスペースを占有しているので、次の制約

[NSLayoutConstraint constraintWithItem:_rightLabel 
        attribute:NSLayoutAttributeLeft 
        relatedBy:NSLayoutRelationGreaterThanOrEqual 
        toItem:_leftLabel 
        attribute:NSLayoutAttributeRight 
        multiplier:1 
        constant:10] 

で相互にリンクされています元のフォントサイズは、テキストが切り捨てられないようにadjustsFontSizeToFitWidthのおかげで低下します。

私の問題は、長いテキストのためにフォントサイズを下げる必要があるときに、もう一方のラベルでフォントサイズを下げて両方のサイズを同じサイズにする。私はフォントのサイズを制限することもしたいですが、悲しいかな、私はこれにどのようなアイデアを知らないのですか?

+0

両方のラベルの間に等しい幅の制約を課すことで、目的の効果のようなものを得ることができました。(最後の2文字は..で切り捨てられますが、フォントのスケーリングは同じです) – Aodh

答えて

-1

key-value observingを使用して1つのラベルのフォントプロパティの変更を観察し、同じフォントを使用するようにもう一方のラベルを設定することができます。あなた-viewDidLoad方法において

:同じコントローラの実装で

// Add self as an observer of _rightLabel's font property 
[_rightLabel addObserver:self forKeyPath:@"font" options:NSKeyValueObservingOptionNew context:NULL]; 

(上記のコードでは、自己コンテキストスニペット):UILabel documentation on adjustsFontSizeToWidthから

// Observe changes to the font property of _rightLabel 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if (object == _rightLabel && [keyPath isEqualToString:@"font"]) { 
     // Set _leftLabel's font property to be the new value set on _rightLabel 
     _leftLabel.font = change[NSKeyValueChangeNewKey]; 
    } 
} 
+0

私は'adjustsFontSizeToFitWidth'を使うとフォントのプロパティが変わることがあります。 'font'の値は変更されませんが、表示されるときは、より小さなフォントサイズでレンダリングされます。 – Jackson

+0

[調整されたフォントサイズを計算する唯一の方法](http://stackoverflow.com/questions/3669844/how-to-get-uilabel-uitextview-auto-adjusted-font-size/6141770#6141770) iOS 7では非推奨です。 – Jackson

13

通常、ラベルテキストは、指定したフォントで描画されます。フォントプロパティ。ただし、このプロパティがYESに設定されていて、テキストプロパティ内のテキストがラベルの境界矩形を超える場合、受信者は文字列が収まるか最小フォントサイズに達するまでフォントサイズの縮小を開始します。

これは、更新されたフォントが描画時に計算され、fontプロパティが読み取られ、書き込まれないことを意味します。したがって、私はAndrewがfontプロパティでKVOを使用する提案はうまくいかないと考えています。

結果的に、調整したフォントサイズを計算する必要があります。

コメントにJacksonがコメントしているように、実際のフォントを取得するthis very convenient NSString methodは、iOS 7では廃止されました。技術的には、削除するまで使用することができます。

もう1つの方法は、両方のラベルに適合するフォントスケールを見つけるまで、フォントスケールをループすることです。私はそれをうまく動作させることができました。 here's a sample project that shows how I did it

また、ここではこれまでにリンクした場合のコードは動作を停止します:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:_rightLabel 
                    attribute:NSLayoutAttributeLeft 
                    relatedBy:NSLayoutRelationGreaterThanOrEqual 
                    toItem:_leftLabel 
                    attribute:NSLayoutAttributeRight 
                   multiplier:1 
                    constant:10]; 

    [self.view addConstraint:constraint]; 
} 

- (IBAction)makeRightLabelLongerPressed:(id)sender { 
    self.rightLabel.text = @"some much longer right label text"; 
} 

- (IBAction)adjustLabelSizes:(id)sender { 
    NSLog(@"Attempting to adjust label sizes…"); 

    CGFloat minimumScaleFactor = fmaxf(self.rightLabel.minimumScaleFactor, self.leftLabel.minimumScaleFactor);; 
    UIFont * startingFont = self.rightLabel.font; 

    for (double currentScaleFactor = 1.0; currentScaleFactor > minimumScaleFactor; currentScaleFactor -= 0.05) { 
     UIFont *font = [startingFont fontWithSize:startingFont.pointSize * currentScaleFactor]; 
     NSLog(@" Attempting font with scale %f (size = %f)…", currentScaleFactor, font.pointSize); 

     BOOL leftLabelWorks = [self wouldThisFont:font workForThisLabel:self.leftLabel]; 
     BOOL rightLabelWorks = [self wouldThisFont:font workForThisLabel:self.rightLabel]; 
     if (leftLabelWorks && rightLabelWorks) { 
      NSLog(@" It fits!"); 
      self.leftLabel.font = font; 
      self.rightLabel.font = font; 
      return; 
     } else { 
      NSLog(@" It didn't fit. :-("); 
     } 

    } 

    NSLog(@" It won't fit without violating the minimum scale (%f), so set both to minimum. Some text may get truncated.", minimumScaleFactor); 

    UIFont *minimumFont = [self.rightLabel.font fontWithSize:self.rightLabel.font.pointSize * self.rightLabel.minimumScaleFactor]; 
    self.rightLabel.font = minimumFont; 
    self.leftLabel.font = minimumFont; 
} 

- (BOOL) wouldThisFont:(UIFont *)testFont workForThisLabel:(UILabel *)testLabel { 
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:testFont, NSFontAttributeName, nil]; 
    NSAttributedString *as = [[NSAttributedString alloc] initWithString:testLabel.text attributes:attributes]; 
    CGRect bounds = [as boundingRectWithSize:CGSizeMake(CGRectGetWidth(testLabel.frame), CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) context:nil]; 
    BOOL itWorks = [self doesThisSize:bounds.size fitInThisSize:testLabel.bounds.size]; 
    return itWorks; 
} 

- (BOOL)doesThisSize:(CGSize)aa fitInThisSize:(CGSize)bb { 
    if (aa.width > bb.width) return NO; 
    if (aa.height > bb.height) return NO; 
    return YES; 
} 

このアプローチは自明ジャクソンにリンクされている非推奨メソッドを置き換えるカテゴリメソッドにリファクタリングすることができます。

+0

あなたのシナリオを完全に理解しているかどうかはわかりません。私が思っていることが正しいと思うなら、おそらく、あなたが記述した2つの連結テキストを含む3番目のラベルを追加することができます。新しいラベルは透明で、その唯一の目的は適切なフォントサイズを確立することです。ラベルのサイズ。そうすれば、他の2つのラベルは、透明ラベルと同じフォントサイズを使用して、適切に揃えることができます。 –

+0

@VictorEngelこのコードは、3番目のラベルを付けずに正しいフォントサイズを設定します。プロジェクトをダウンロードして実行してみてください。 –

+0

確かに。私は、自動レイアウトだけを使った代替案を提案していました。あなたの答えに対するコメントではなく、オリジナルの質問に対するコメントであることを意図していました。それがここでどのように終わったかわからない。申し訳ありません。 –

1

私はより良い解決策を見つけました。テキストの長さがより短いuilabelには、最初から最後までの間に、テキストスペースを追加するだけです。そしてフォントは同じです。

+1

これは私を笑わせてくれました - 私は100%時間がかからなくても、そのシンプルさが大好きです。フォントが固定幅でない場合、スペースは他のほとんどの文字と同様にセーブ幅ではありません。 'w'(非常に広い)の文字列が長い文字列の場合、スペースパディング付きの短い文字列よりも長くなります。つまり、文字の量が同じであっても、必ずしも同じ幅であるとは限りません。多くの場合、それは働くには十分に近いでしょう。 –

関連する問題