web-dev-qa-db-ja.com

AutoMaxoutは、preferredMaxLayoutWidthが設定されている場合、UILabel iPhone 6/6 +の上下に追加のパディングを追加します

これを再現するサンプルプロジェクトを作成しました。

固定のトップ、リーディング、トレーリングの制約があるUILabelを持つxibファイルがあります。 minHeight制約を追加して、行数を0に設定しました。

PreferredMaxLayoutWidthをAutomaticに設定しました(xibファイルでチェックされています)。

ViewDidLoadでは、私はこれを持っています:

self.myLabel.layer.borderColor = [[UIColor redColor] CGColor];
self.myLabel.layer.borderWidth = 2.0f;
self.myLabel.text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";

そして、iPhone 6または6+でシミュレーターを実行すると、次のようになります。

enter image description here

私はその上下のパディングがどこから来ているのかわからず、UILabelの文字数に比例しています。

忘れていた魔法の設定はありますか? iPhone 4 "デバイスで問題なく動作します。

これで、preferredMaxLayoutWidthを設定しない場合、追加のパディングはありませんが、UILabelの複数行が壊れます。テキストを切り取ります。サイズクラスは使用しませんでした。

編集:

そのため、実際のプロジェクトの状況に合わせて、サンプルプロジェクトのいくつかを変更しました。 tableViewを追加しました(上位、上位、下位、末尾の制約をその親ビューに設定しています)。 tableViewの各セルには4つのラベルがあります。上部のラベルには、セルのcontentViewに対する上部の先行制約と後続の制約があり、後続のラベルには、その上のラベルに対する垂直制約があります。すべてのラベルには、heightGreaterThan制約セットとwidthGreaterThanセットがあります。

これは、preferredMaxLayoutWidthを設定しない場合の外観です(ラベルが1行に制限されることに注意してください)。 No preferredMaxLayoutWidth

PreferredMaxLayoutWidthを使用します。 UILabelはコンテンツ全体を表示しますが、上下にパディングがあります。 With preferredMaxLayoutWidth but with top and bottom padding

Edit2:サンプルプロジェクト: https://www.dropbox.com/s/sdahx9njnsxiv98/MultiLineUILabel.zip?dl=1 =

24
newDeveloper

つまり、ラベルのサブクラスを作成し、setBounds:をオーバーライドして、preferredMaxLayoutWidthをその境界に設定することになります。

- (void)setBounds:(CGRect)bounds {
    [super setBounds:bounds];

    if (self.preferredMaxLayoutWidth != bounds.size.width) {
        self.preferredMaxLayoutWidth = bounds.size.width;
        [self setNeedsUpdateConstraints];
}}

また、UITableViewCellサブクラスで、layoutSubiewsをオーバーライドします

- (void)layoutSubviews {
    [super layoutSubviews];

    [self.contentView layoutIfNeeded];

    // labelsCollection is an IBOutletCollection of my UILabel sublasses
    for (UILabel *label in self.labelsCollection) {
        label.preferredMaxLayoutWidth = label.bounds.size.width;
}}

これは常に機能します。この奇妙な動作の理由は、UILabelがxibファイルで最初に280px(320px-どちらかの側のパディング)に設定されているが、実行時に、より大きな画面に対応するために幅を変更するためです(先頭と末尾を設定したため)制約により幅が増加し、「preferredMaxLayoutWidth」がより大きな値に変更されます)。何らかの理由で、UILabelはそのpreferredMaxLayoutWidthをより大きい値に更新せず、上下に空白を生じさせます。

それが私の仮説です。

お役に立てれば。

8
newDeveloper

このクラスを使用して私のために修正しました

import UIKit

class CustomLabel: UILabel {

    override func drawText(in rect: CGRect) {
        if let stringText = text {
            let stringTextAsNSString = stringText as NSString
            let labelStringSize = stringTextAsNSString.boundingRect(with: CGSize(width: self.frame.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil).size
            super.drawText(in: CGRect(x: 0, y: 0, width: self.frame.width, height: ceil(labelStringSize.height)))
        } else {
            super.drawText(in: rect)
        }
    }

}
1
user1974368

既にmaxPreferredLayoutWidthを使用しているこの質問を調べている人(サブクラスにする必要はありません。VCのviewDidLayoutSubviewsでこれを設定するだけです)は、正しいビューの幅に設定していることを確認してください。

私が持っていたので鉱山は働いていませんでした:

label1.maxPreferredLayoutWidth = label1.frame.width
label2.maxPreferredLayoutWidth = label1.frame.width

あるべき時:

label1.maxPreferredLayoutWidth = label1.frame.width
label2.maxPreferredLayoutWidth = label2.frame.width

違いがわかりますか? 3時間もしなかったww

1
Abbey Jackson

ラベルの下部に制約はありますか?私は、コンテンツを優先する優先順位のために、それが伸びることを可能にしていると思います。 1000に設定します(必須)。これにより、テキストサイズを超えて拡大するのを防ぎます。次に、ラベルの下部に適切な制約を追加する必要があります。

0
Henry T Kirk

まず最初に、私の英語でごめんなさい。私は英語の初心者ですが、この問題をどのように修正したかを説明します。

私はいくつかのプロジェクトでこの問題に直面しました。だからこれを修正する私の解決策は:

  1. セルには次の構成メソッドがあります:-(void)configureWithSomeObject:parentViewSize:とtableView:cellForRowAtIndexPath:このようにセルを作成しました:

    - (UITableViewCell *)tableView:(UITableView *)tableView  cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    YourCell *cell;
    
    //cell initialization
    
    [cell configureWithSomeObject:nil parentViewSize:tableView.frame.size];
    
    return cell;
    }
    
  2. 内部構成メソッドは、親の幅に応じて、preferredMaxLayoutWidthを設定するだけです。

     - (void)configureWithSomeObject:(NSObject)someObject parentViewSize:(CGSize)parentViewSize {
    // do your stuff
    
    self.someLabel.preferredMaxLayoutWidth = parentViewSize.width;
     }
    

追伸先頭/末尾にスペースがある場合は、parentViewSize.width値からそれを差し引く必要があります。

それが誰にとっても役立つことを願っています:)

0
Oleg Sorochich

IOS 7との互換性のためにpreferredMaxLayoutWidthを設定する必要があったので、必要なラベルの高さを計算するためにboundingRectWithSizeを呼び出し、UILabelの公開された高さ制約の定数を設定しました。

CGRect labelRect = CGRectIntegral([myText boundingRectWithSize:size 
    options:options attributes:attributes context:context]);
self.myLabelHeightConstraint.constant = labelRect.size.height;
0
AlexD

これがSwiftに実装した方法です。UILabelを拡張するクラスで、スーパーの境界変数を設定して返すゲッターとセッターで境界変数をオーバーライドします。これにより、コードをgetおよびsetに追加できます。 。

私はそれがまだすべての魔法をやっているとは確信していません、私はまだ大きなオープンスペースを持っています。

    override var bounds:CGRect {
        get {
            return super.bounds
        }
        set {
            super.bounds = newValue
            if (self.preferredMaxLayoutWidth != super.bounds.size.width) {
                self.preferredMaxLayoutWidth = super.bounds.size.width;
                self.setNeedsUpdateConstraints()
            }
        }
    }
0
Mathijs Segers

UILabelはテキストを垂直方向に中央揃えにします。私はあなたが見ているものを推測しているのは、あなたの制約がラベルのビューをより大きなデバイスで引き伸ばしていることであり、テキストは予想通り、サイズの付いたビューの垂直方向の中央に配置されていることです。

代わりに、UIViewContentModeTopで編集不可のUITextViewを使用してみてください。

0
stromdotcom

同様の問題があり、UILabelをサブクラス化してsetBoundsをオーバーライドするだけでは機能しませんでした。 setBoundsをステップ実行すると、ラベルの高さが39.999999993であることがわかりました。そこで、次の変更を加えて、40に丸めました。

- (void)setBounds:(CGRect)bounds
{
    bounds.size.height = ceilf(CGRectGetHeight(bounds));

    [super setBounds: bounds];

    if (self.preferredMaxLayoutWidth != bounds.size.width)
    {
        self.preferredMaxLayoutWidth = bounds.size.width;
        [self setNeedsUpdateConstraints];
    }
}

これで問題が解決しました。大きなデバイスでUILabelの上下に余計な余白がなくなりました。また、コンテンツをハグする優先順位を設定する必要もありませんでした。

0
koen