4

NSString読み込まれているテキストに応じてを自動的にサイズ変更する追加機能がありますUILabel(引用を表示する単純なアプリがあるため、いくつかの単語、いくつかの文です)。quoteそのラベルの下にはauthor、(奇妙なことに) 引用の著者が含まれるラベルもあります。

authorそのラベルをラベルのすぐ下に配置しようとしていますquote(そのy座標は、quoteラベルのy座標にquoteラベルのheight. 、サイズが変わります。引用符が小さいほどスペースが多く、引用符が長いほどスペースが少なくなります。

ここに画像の説明を入力 ここに画像の説明を入力

layer.borderColor/borderWidth赤と青のボックス (アプリで表示できるように設定したもの) の間のギャップは、見積もりが短いほど大きくなります。

誰かが以下のコードをふるいにかけて、不一致の原因を正確に指摘するのを手伝ってくれるなら、本当に感謝しています. 私が見る限り、authorラベルは常にquoteラベルのy + height値の 35 ピクセル下にある必要があります。

確認のために: すべてが Interface Builder などで正しく接続されています。引用の内容はそこにうまく入っており、他のすべてが機能しているため、接続されています。それは問題ではありません。

明確にするために、私の質問は次のとおりです。引用符の長さに応じてラベル間のギャップが変化するのはなぜですか?35ピクセルの安定した設定可能なギャップを正しく取得するにはどうすればよいですか?

ラベルを配置するために使用しているコードは次のとおりです。

// Fill and format Quote Details
_quoteLabel.text = [NSString stringWithFormat:@"\"%@\"", _selectedQuote.quote];
_authorLabel.text = _selectedQuote.author;
[_quoteLabel setFont: [UIFont fontWithName: kScriptFont size: 28.0f]];
[_authorLabel setFont: [UIFont fontWithName: kScriptFontAuthor size: 30.0f]];

// Automatically resize the label, then center it again.
[_quoteLabel sizeToFitMultipleLines];
[_quoteLabel setFrame: CGRectMake(11, 11, 298, _quoteLabel.frame.size.height)];

// Position the author label below the quote label, however high it is.
[_authorLabel setFrame: CGRectMake(11, 11 + _quoteLabel.frame.size.height + 35, _authorLabel.frame.size.width, _authorLabel.frame.size.height)];

のカスタムメソッドは次のsizeToFitMultipleLinesとおりです。

- (void) sizeToFitMultipleLines
{
    if (self.adjustsFontSizeToFitWidth) {
        CGFloat adjustedFontSize = [self.text fontSizeWithFont: self.font constrainedToSize: self.frame.size minimumFontSize: self.minimumScaleFactor];
        self.font = [self.font fontWithSize: adjustedFontSize];
    }
    [self sizeToFit];
}

そして、ここに私のfontSizeWithFont:constrainedToSize:minimumFontSize:方法があります:

- (CGFloat) fontSizeWithFont: (UIFont *) font constrainedToSize: (CGSize) size minimumFontSize: (CGFloat) minimumFontSize
{
    CGFloat fontSize = [font pointSize];
    CGFloat height = [self sizeWithFont: font constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
    UIFont *newFont = font;

    // Reduce font size while too large, break if no height (empty string)
    while (height > size.height && height != 0 && fontSize > minimumFontSize) {
        fontSize--;
        newFont = [UIFont fontWithName: font.fontName size: fontSize];
        height = [self sizeWithFont: newFont constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
    };

    // Loop through words in string and resize to fit
    for (NSString *word in [self componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]) {
        CGFloat width = [word sizeWithFont: newFont].width;
        while (width > size.width && width != 0 && fontSize > minimumFontSize) {
            fontSize--;
            newFont = [UIFont fontWithName: font.fontName size: fontSize];
            width = [word sizeWithFont: newFont].width;
        }
    }
    return fontSize;
}
4

3 に答える 3

1

両方のラベルに合わせてサイズを呼び出した後、フレーム間の距離を計算し、それに応じて変更します。

[quoteLabel sizeToFit];
[authorLabel sizeToFit];

float distance = authorLabel.frame.origin.y - quoteLabel.frame.size.height;
float difference = distance - 35;

authorLabel.frame = CGRectMake(authorLabel.frame.origin.x,(authorLabel.frame.origin.y - difference),authorLabel.frame.size.width,authorLabel.frame.size.height);

ギャップが変化する理由は、sizeToFit を呼び出すと、その内容に応じて引用ラベル フレームの高さが変化するためです。

アップデート

コメントの最近の展開を考えると、3 つの可能性があると思います。

  • 文字列が実際にフレームに正しく収まるように、単語だけでなく空白のサイズを変更します
  • 何らかの方法で UILabel の CTFramesetter にアクセスして、実際のフレームが何を意味するかを確認します。
  • draw rect メソッドで Core Text 描画を処理する独自の UIView サブクラスを作成します (あなたの場合は簡単なはずです)。
于 2013-04-04T13:42:19.017 に答える
1

おそらく必要な場所に移動していますが、その後、自動レイアウト制約またはスプリング/ストラットが移動しています。

編集:
の最初の考え(単語の周りのボックスはラベルフレームであるとあなたが言ったので除外しました。後のコメントで、これは実際のスクリーンショットではなく、単なる表現であると言っているので、まだ可能性があります正しい)は、あなたがこれを間違っているということでした:

[_quoteLabel sizeToFitMultipleLines];
[_quoteLabel setFrame: CGRectMake(11, 11, 298, _quoteLabel.frame.size.height)];

1 行目では、現在のラベルの幅に合わせてテキストのサイズを変更し、2 行目で向きを変えてラベルの幅を変更します。おそらく、ラベルのサイズを少し小さくして、ラベルの高さを大きくしている可能性があります。次に、ラベルの幅を以前よりも広くすると、テキストは幅の広いラベルに合わせて拡張され、実際のテキストの下に空白の領域が残りますが、フレームは変更されていません。これにより、ラベル間のスペースが希望どおりに正確に 35 になりますが、上部のラベルのテキストがフレームの下部まで届かないため、余白が必要以上に多くなります。基本的に、あなたはこれを持っています:

*************
* text text *
* text text *
*           *
*           *
*           *
*************

*************
* text text *
*************

この場合は、次のように最初に幅を設定して修正します。

// You could put anything for the 200 height since you will be changing it in the next line anyway.
[_quoteLabel setFrame: CGRectMake(11, 11, 298, 200];  
[_quoteLabel sizeToFitMultipleLines];
于 2013-04-04T13:54:04.717 に答える