web-dev-qa-db-ja.com

自動レイアウトのみを使用したiOS8 Today拡張機能の高さにより、制約が壊れる

Appleのドキュメントでは、自動レイアウトを使用してToday Extensionsの高さを設定することを推奨しています。

ウィジェットに表示する追加コンテンツがある場合、自動レイアウト制約を使用して、必要に応じてウィジェットの高さを調整できます。自動レイアウトを使用しない場合、UIViewControllerプロパティのpreferredContentSizeを使用して、ウィジェットの新しい高さを指定できます。

ただし、私が見たすべての例とチュートリアルでは、preferredContentSizeを使用しています。

自動レイアウトを介して高さを設定しようとするすべての試みは、制約が壊れているという警告につながります。

自動レイアウトによる高さの設定

私は新鮮なXcodeテンプレートと新鮮な今日の拡張テンプレートから始めました。 TodayViewController.mに追加した唯一のものは:

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
    return UIEdgeInsetsMake(0, 0, 0, 0);
}

注:デフォルトのマージンのみを使用すると、この問題が発生します。

ラベルの高さを制限し、ラベルをコンテナの中央に配置し、コンテナの高さをラベルの高さと同じになるように制限しました。

Constrained Height

これにより、制約が競合することなく、指定された高さでコンテナを満たすラベルが作成されます。代わりに、制約の競合が発生します。

2014-09-28 10:27:39.254 TodayExtension[61090:2672196] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7f8b8b62c670 V:[UILabel:0x7f8b8b62d9b0'Hello World'(124)]>",
    "<NSLayoutConstraint:0x7f8b8b583020 UIView:0x7f8b8b62d6e0.height == UILabel:0x7f8b8b62d9b0'Hello World'.height>",
    "<NSLayoutConstraint:0x7f8b8b5888a0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7f8b8b62d6e0(667)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7f8b8b62c670 V:[UILabel:0x7f8b8b62d9b0'Hello World'(124)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

それが制約を破る方法は、実際に私がそれをしたいように見えます: Constrained Height View

ただし、他のプロジェクトでは、他の制約を破ることを決定し、正しく見えません。また、サイドノート:高さ制約の優先度を変更しようとすると、Xcodeがクラッシュします。それは楽しいです。

高さを制限しない

コンテナの高さをサブビューに制限しないと、サブビューを格納して適切に設定するために必要な高さを見つけられるかもしれないので、高さの制限がうまくいかないことを期待していました。

サブビューを中央に配置し、高さを制限しました。i.imgur.com/PwLmhj9.png

これにより、通知センターの全高を使い尽くす拡張機能と、垂直方向の中央に正しいサイズのビューが表示されました。

i.imgur.com/kKXlocu.png

中央に配置せずに、上部のレイアウトガイドに垂直方向のスペースを固定すると、サブビューが上部に固定されることを除いて、同じことがわかります(ただし、コンテナーはまだ巨大です)。

何が得られますか?

私はpreferredContentSizeを使用できることを知っていますが、なぜApple= Auto Layout制約を使用して設定できると言うのですか?何が間違っていますか?

私が与えた例は明らかに不自然です。ビューの高さを設定しているので、コンテナの高さを設定しないでください。実際のプロジェクトにおけるこの点の一部は、自動レイアウトのみを使用して、幅に基づいてウィジェットの高さを設定することです。

43
Ryan C.

いくつかの実験を行い、「 NSLayoutConstraint "UIView-Encapsulated-Layout-Height"とは何か、どうすればきれいに再計算するように強制するか 」に出くわした後、「 「高さ」と「等しい高さ」OR「高さ」および上下の「垂直方向のスペース」( Guilherme Sprint で示唆されているように)高さ制約の999へ。

Height Constraint with Reduced Priority

これは私が望んでいた答えではありません、しかしサブビューの自動レイアウトを介してコンテナの高さを指定し、破損に関する警告を回避します制約。

私の完全に非科学的な推測/仮定/結論は、iOSがレイアウト制約を正しく見てコンテナビューの高さを決定しているということです。次に、計算した高さと同じ高さの新しい制約を追加しますが、これにより高さが過剰に制約されます。元の開発者が指定した高さの制約の優先度を下げると、システムで生成された制約が優先され、警告は生成されません(実際に知っている人からこれについて詳しく知りたいと思います)。

36
Ryan C.

Today Extensionを本当に必要なサイズにするために、合計5つの制約を定義する必要があります。

4つの制約により、スーパービューとの関係が定義されます。

  • トップスペース
  • ボトムスペース
  • リーディングスペース
  • 後続スペース

ところで、Appleがビュー、特にToday Extensionsを推奨しているように、この制約をレイアウトマージンにフックする必要があります。

5番目の制約は、サブビューの高さです。この制約は、上部と下部のスペースとともに、Todayタブ内のセクションの正確なサイズを定義します。

Xcode Today Extension Constraints

それを説明するだけで、高さの制約はサブビューの定数を設定し、上部と下部の制約はスーパービューをサブビューの端に「接着」します。

Today Extension running

5
Gui Moura

ラベルの高さにより、これらの制約を同時に満たすことができなくなります。

  • ラベルの最小の高さ
  • スーパービューするトップスペース
  • スーパービューの下部スペース

ボトムスペースからスーパービューへの制約を削除することで解決できます。自動レイアウトシステムはボトムスペースに残りのスペースを割り当てます。

0
Freeman