82

ペン先を介して初期化されているカスタム UIView サブクラスがあります。

-awakeFromNib、サブビューを作成し、それをスーパービューの中央に配置しようとしています。

[self setInteralView: [[UIView alloc] init]];
[[self internalView] addConstraint: [NSLayoutConstraint constraintWithItem: [self internalView]
                                                                 attribute: NSLayoutAttributeCenterX
                                                                 relatedBy: NSLayoutRelationEqual
                                                                    toItem: self
                                                                 attribute: NSLayoutAttributeCenterX
                                                                multiplier: 1
                                                                  constant: 0]];

これは壊れ、次の出力が発生します。

2013-08-11 17:58:29.628 MyApp[32414:a0b] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0xc1dcc80 UIView:0xc132a40.centerX == MyView:0xc1315a0.centerX>
    When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug.
2013-08-11 17:58:29.630 MyApp[32414:a0b] View hierarchy unprepared for constraint.
    Constraint: <NSLayoutConstraint:0xc1dcc80 UIView:0xc132a40.centerX == MyView:0xc1315a0.centerX>
    Container hierarchy: 
<UIView: 0xc132a40; frame = (0 0; 0 0); clipsToBounds = YES; layer = <CALayer: 0xc132bc0>>
    View not found in container hierarchy: <MyView: 0xc1315a0; frame = (-128 -118; 576 804); layer = <CALayer: 0xc131710>>
    That view's superview: <UIView: 0xc131a70; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0xc131b50>>
4

8 に答える 8

95

エラーが示すように、制約に含まれるビューが追加先のビューまたはそのビューのサブビューになるように、制約をビューに追加する必要があります。上記のコードの場合、その制約をselfではなくに追加する必要があります[self internalView]。書かれているように機能しない理由は、制約に関係するビューの 1 つです (selfのみを考慮すると、ビュー階層にありません[self internalView])。

詳細については、メソッドに関するドキュメントのディスカッション セクションを参照してください。addConstraint:

私が提案するように修正されたコード行は次のとおりです。

UIView* internalView = [[UIView alloc] initWithFrame:CGRectZero];
internalView.translatesAutoresizingMaskIntoConstraints = NO;
[self setInternalView:internalView];

[self addConstraint: [NSLayoutConstraint constraintWithItem: [self internalMapView]
                                         attribute: NSLayoutAttributeCenterX
                                         relatedBy: NSLayoutRelationEqual
                                         toItem: self
                                         attribute: NSLayoutAttributeCenterX
                                         multiplier: 1
                                         constant: 0]];
于 2013-08-11T22:23:32.423 に答える
36

簡単な答え:親ビューと子ビューを入れ替えます。親ビューである
と仮定します:self

  • 悪い:[subview addConstraint [NSLayoutConstraint constraintWithItem:self...

  • 良い:[self addConstraint [NSLayoutConstraint constraintWithItem:subview...


迅速

subview.translatesAutoresizingMaskIntoConstraints = false
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(
    "H:|-0-[subview]-0-|",
    options: .DirectionLeadingToTrailing,
    metrics: nil,
    views: ["subview":subview]))

オブジェクト-C

[subview setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addConstraints:[NSLayoutConstraint
                      constraintsWithVisualFormat:@"H:|-0-[subview]-0-|"
                      options:NSLayoutFormatDirectionLeadingToTrailing
                      metrics:nil
                      views:NSDictionaryOfVariableBindings(subview)]];
于 2015-07-23T05:39:38.980 に答える
10

追加のヒント:

iOS7 では正常に動作する新しく開発されたアプリがありますが、iOS8 では「ビュー階層が制約に対して準備されていません」というエラーが発生します。

制約を作成する前に(サブ)ビューを追加する必要があると述べた他の投稿を読んでください。私はそれをしましたが、それでもエラーが発生しました。

次に、viewDidLoad の代わりに -(void)viewDidAppear の下に制約を作成する必要があることがわかりました。

于 2015-05-19T16:54:40.037 に答える
6

これは古い質問ですが、ドキュメントから次の行を指摘したいと思います。

iOS 8.0 以降向けに開発する場合は、addConstraint(_:) メソッドを直接呼び出すのではなく、制約の isActive プロパティを true に設定します。isActive プロパティは、正しいビューから制約を自動的に追加および削除します。

少なくとも、これにより、間違ったビューで addConstraint を呼び出すことを心配する必要がなくなるため、1 つの障害点が取り除かれます。

于 2017-05-25T21:23:46.427 に答える
1

@CharlesA が彼の回答で指摘しているように、問題は、追加するビューが適切なビュー階層にないことです。彼の答えは良いものですが、この問題を引き起こした特定のユースケースについて詳しく説明します。

を使用してインスタンス化したView Controllerのビューに制約を追加しようとしたときに、これが発生しましたinstantiateViewControllerWithIdentifier。問題を解決するために、 を使用し[childViewController didMoveToParentViewController:self]ました。これにより、制約によって参照されたビュー階層にビューが追加されました。

于 2014-06-29T15:23:19.383 に答える
0

最初にサブビューを追加してから、次のように制約を追加します

addSubview(yourSubViewHere)
yourSubViewHere.translatesAutoresizingMaskIntoConstraints = false

addConstraint(NSLayoutConstraint(....
于 2019-09-27T10:52:28.187 に答える