自動レイアウトを使用してサブビューが動的に変更された後、スーパービューのサイズを変更する


83

私は神の愛のためにこのサイズ変更のスーパービューのこつを傾けることができません。

私はUIView *superview 4で持っていUILabelsます。2は他の2つのヘッダーとして機能します。

4つすべてのコンテンツは、データベースから動的に取得されます。

SizeToFitvs SizeThatFits:(CGSize)vs UIView systemLayoutSizeFittingSize:UILayoutFittingCompressedSizeまたはのいずれかを渡しますUILayoutFittingExpandedSize

プログラムで自動レイアウトを使用し、スーパービューの高さをダミーの数値以上に設定しました。

どこで、どのように私はこれらを使用しないSizeToFitsizeThatFits:(CGSize)UIView systemLayoutSizeFittingSize:のいずれか渡し、UILayoutFittingCompressedSizeまたはUILayoutFittingExpandedSize。私はここでスタックで多くのヒントを読みましたが、結局何もありませんでした。

特定の場所でスーパービューの制約を再計算する必要がありますか?Mabyは、コントローラークラスで高さを「@property」に設定し、それを削除して読み取りましたか?Atm私はすべてをどこにでも置いてからいくつかを入れようとしました。それでも、ダミーの高さとテキストが外側に浮いている状態で、同じサイズの最終結果が得られます。サブビューでclipsToBoundを設定した後でも。

私は私の髪を引っ掻いています..助けて


1
ねえ、私が見てみることができれば、あなたのコードをペーストビンか何かのどこかに投稿できますか?私も同様の問題に苦しんでいます。一週間以上経ちました。
esh 2014年

回答:


104

自動レイアウトを使用している場合は、次のことを行う必要があります。

  1. サブビューに固定の幅や高さの制約を追加していないことを確認してください(動的にサイズを設定する寸法によって異なります)。アイデアは、各サブビューの固有のコンテンツサイズがサブビューの高さを決定するようにすることです。UILabel■4つの自動暗黙的制約が付属しており、(必要な優先度未満で)ラベルのフレームをすべてのテキストを内部に収めるのに必要な正確なサイズに維持しようとします。

  2. 各ラベルのエッジが、相互のエッジとそのスーパービューに(必要な優先度の制約を使用して)しっかりと接続されていることを確認してください。ラベルの1つがサイズが大きくなることを想像した場合、他のラベルにそのためのスペースを確保し、最も重要なこととして、スーパービューも拡大することを確認する必要があります。

  3. スーパービューに制約を追加して、サイズではなく位置を設定するだけです(少なくとも、動的にサイズを設定する寸法については追加しません)。内部制約を正しく設定すると、そのエッジが何らかの方法でサブビューに接続されているため、そのサイズはすべてのサブビューのサイズによって決定されることに注意してください。

それでおしまい。電話をかけsizeToFitたりsystemLayoutSizeFittingSize:、これを機能させる必要はありません。ビューを読み込んでテキストを設定するだけで、それで十分です。システムレイアウトエンジンは、制約を解決するための計算を行います。(どちらかといえばsetNeedsLayout、スーパービューを呼び出す必要があるかもしれません...しかし、これは必須ではありません。)


smileyborgに感謝します。私がプロジェクトの途中で、あなたが言ったことを完全に理解できなかったので、遅い応答。今、私はプログラムで、特にで制約を使ってもう少し作業する機会がありましconstraintsWithVisualFormatた。含まれているサブビューが伸びて、スーパービューをそのサイズに押し出すことについて完全にあなたの意見を聞きました:)ありがとう
Pedroinpeace 2013年

私は解決策に同意しますが、それは私のために機能していません、stackoverflow.com / questions
34635838 /を

この答えは魔法です。ビューを美しく見せるための私の側の労力ははるかに少なくなります。
クリス

1
translatesAutoresizingMaskIntoConstraints = NOxibを使用している場合は、設定する必要があることに注意してください。
KudoCC 2017年

translatesAutoresizingMaskIntoConstraints = NOが私の場合の答えです。しかし、コンテナビューでフレームが失われ、その原点は常に(0,0)であるため、希望の場所に配置できません。stackoverflow.com/questions/45548372/...
カリム・

24

コンテナビューを使用する

次の例では、30x30の画像がありUILabel、プレースホルダーテキストを含むビューよりも小さくなっています。含むビューは少なくとも画像と同じ大きさである必要がありましたが、複数行のテキストを含むように拡大する必要がありました。

視覚的な形式では、内部コンテナは次のようになります。

H:|-(15.0)-[image(30.0)]-(15.0)-[label]-(15.0)-|
V:|[image(30.0)]|
V:|[label(>=30.0)]|

次に、ラベルの高さに一致するように包含ビューを設定します。これで、含まれているビューがラベルのサイズになります。

@smileyborgが彼の回答で指摘したように、コンテンツをスーパービューに厳密に接続すると、単純なコンテナビューによってコンテンツが大きくなるはずであることがレイアウトエンジンに通知されます。

黄色の配置長方形

黄色の配置長方形が必要な場合-UIViewShowAlignmentRects YESは、スキームの実行引数のリストに追加します。

複数行のUILabel


12
-UIViewShowAlignmentRects YES-すばらしいヒントです。
ラルフォンソ2015年

2
この場合、コンテナはその高さをラベルに適合させるだけで済みます。コンテナが複数のビューの高さの合計に適応する必要がある場合はどうなりますか?
da Rocha Pires 2015年

7

これは、iOS 9にスタックビューが導入されたことで劇的に簡単になりました。ビュー内でスタックビューを使用して、サイズを変更するすべてのコンテンツを含めてから、

view.setNeedsUpdateConstraints()
view.updateConstraintsIfNeeded()
view.setNeedsLayout()
view.layoutIfNeeded()

コンテンツを変更した後。次に、電話して新しいサイズを取得できます

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

ビューに必要な正確なサイズを計算する必要がある場合。


2
StackViewを使用してビューを動的に追加していますが、これらのビューのサイズは変更されていません。@ JacobRuth
Mansuu ....

6

これは@smileyborgの回答にほぼ続き、具体的な例が付属しています。

ここに画像の説明を入力してください

すべての制約について説明するわけではありませんが、UIオブジェクトの高さの計算に関連する制約について説明します。

  1. [ラベル]ラベルに固定height制約を設定することはできません。この場合、AutoLayoutはテキストに合わせてラベルのサイズを変更しないため、エッジ制約を設定することが重要です。(緑色の矢印)
  2. [サブビュー]手順1と3は非常に簡単ですが、この手順は誤解される可能性があります。ラベルの場合と同様に、サブビューにheight制約を設定してはなりません。すべてのサブビューには、top制約を無視して制約を設定する必要がありbottomます。これにより、実行時に不満足な制約例外がトリガーされると思われる可能性がありますがbottom、最後のサブビューに制約を設定した場合はトリガーされません。そうしないと、レイアウトが壊れてしまいます。(赤い矢印)

  3. [概要]すべての制約を必要に応じて設定しますが、制約には十分注意してください height。ランダムな値を割り当てますが、オプションにします。AutoLayoutは、サブビューにぴったり合うように高さを設定します。(青い矢印)

これは完全に機能し、追加のシステムレイアウト更新メソッドを呼び出す必要はありません。


高さをオプションにする方法..私はiOSを初めて使用するので、理解できません。ありがとう
Faisal Naseer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.