web-dev-qa-db-ja.com

UILabelsizeToFitと制約

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

内容が異なるいくつかのビューを列に表示したいと思います。そして、それらを次々に配置したい(私はこのような制約を使用してレイアウトを作成しました)

initial layout

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

after size to fit call

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

14
Nik

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

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

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

- (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を更新して、ラベルを強制的にリフローして高さを調整する必要があります。そうしないと、ビューのサイズが変更/回転された場合、自動レイアウトはラベルのリフローとサイズ変更の必要性を認識しません。

44
Mike Weller

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

[self.lblBadgeValue sizeToFit];
self.constraintWidthBadgeLabel.constant =  self.lblBadgeValue.frame.size.width;
[self.lblBadgeValue needsUpdateConstraints];
[self.lblBadgeValue layoutIfNeeded];
  • もっと説明してください:
  • sizeToFit->ラベルをその内容に合わせて高さ、幅に合わせます。
  • したがって、実行時に、制約の高さ、またはラベルの幅を更新する必要があります
  • その後、コンパイラに対して、更新制約が必要なものを知っていると言う必要があります。
  • そして最終的に、制約に変更がある場合はレイアウトを呼び出す必要があります。
2
Linh Nguyen