14

コンテンツ サイズを使用して依存ビューの位置を動的に変更するのに役立つ簡単な方法はありますか?

すべてのコンテンツが異なる複数のビューを列に表示したいと考えています。そして、それらを次々に配置したい(このような制約を使用してレイアウトを作成しました)

初期レイアウト

しかし、ラベルの内容を変更して を呼び出すたびにsizeToFit、システムはレイアウトを無視するようです。

コールに合うサイズの後

現時点では、height プロパティのみに関心があります。制約付きの rect も使用できることを知っています。過去に、サイズを動的に変更するために UIView に多くのカテゴリを作成しました (誰もが変更したと思います)。しかし、おそらく私が知らない簡単な方法はありますか?

4

3 に答える 3

44

-sizeToFit自動レイアウトを使用している場合は呼び出さないでください。それは「古い」システムの一部です。

IB が明示的な高さを制約に挿入したようです (ラベルの横の縦棒がこれを示しています)。これらをクリアするには、ラベルを選択して Cmd+= を押してみてください。

複数行のラベルの場合、ビューの回転/サイズ変更時にすべてが正しく機能するように、View Controller で次のことも行う必要があります。

- (void)updateLabelPreferredMaxLayoutWidthToCurrentWidth:(UILabel *)label
{
    label.preferredMaxLayoutWidth =
        [label alignmentRectForFrame:label.frame].size.width;
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label1];
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label2];
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label3];

    [self.view layoutSubviews];
}

複数行のラベルは、自動レイアウトの弱点の 1 つを明らかにします。ラベルを強制的にリフローさせて高さを調整するために更新preferredMaxLayoutWidthする必要があります。そうしないと、ビューのサイズが変更/回転された場合、自動レイアウトはラベルをリフローしてサイズを変更する必要があることを認識しません。

于 2013-04-10T13:35:13.243 に答える
2

ラベルに自動レイアウト制約を引き続き使用する場合。これは解決策です:

[self.lblBadgeValue sizeToFit];
self.constraintWidthBadgeLabel.constant =  self.lblBadgeValue.frame.size.width;
[self.lblBadgeValue needsUpdateConstraints];
[self.lblBadgeValue layoutIfNeeded];
  • もっと説明してください:
  • sizeToFit -> ラベルをコンテンツの高さ、幅に合わせます。
  • したがって、実行時に制約の高さ、またはラベルの幅を更新する必要があります
  • その後、更新制約が必要であることをコンパイラーに知らせる必要があります。
  • そして最後に、制約が変更された場合はレイアウトを呼び出す必要があります。
于 2016-05-26T08:46:23.110 に答える
-1

これも機能します。 https://github.com/jszumski/auto-layout-table-cells/blob/master/DynamicCellHeights/JSLabel.m

@interface JSLabel : UILabel

@end

@implementation JSLabel

- (id)init {
    self = [super init];

    // required to prevent Auto Layout from compressing the label (by 1 point usually) for certain constraint solutions
    [self setContentCompressionResistancePriority:UILayoutPriorityRequired
                                          forAxis:UILayoutConstraintAxisVertical];

    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];

    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);

    [super layoutSubviews];
}

@end
于 2014-01-11T13:13:23.737 に答える