9

に問題がありNSLayoutConstraintます。

constantメソッドを使用して変更しようとすると、NSLayoutConstraintで例外が発生しますsetConstant:。この問題が発生するのは、コードを介して高さ制約を追加した場合のみです。

まず、次のような高さの制約があります。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeWidth];
NSArray *filteredArray = [[self constraints] filteredArrayUsingPredicate:predicate];
return filteredArray[0];

それは私に正しい制約を与えます。これが完全に機能するNSTextFieldサブクラスがあります。制約はInterfaceBuilderで設定され、定数を設定および変更できます。

これで、実行時にさまざまなサブビューを追加するビューができました。これらのサブビューは独自のNIBに配置されているため、幅と高さを固定できません。そのため、ビューがスーパービューに追加されたらすぐに制約を追加すると思いました。これはで実行されていviewDidMoveToSuperviewます。

// Pin Width & Height
[self addConstraint:[NSLayoutConstraint constraintWithItem:self
                             attribute:NSLayoutAttributeWidth
                             relatedBy:NSLayoutRelationEqual
                                toItem:nil
                             attribute:NSLayoutAttributeNotAnAttribute
                            multiplier:1.0f
                              constant:self.frame.size.width]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self
                                                 attribute:NSLayoutAttributeHeight
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:nil
                                                 attribute:NSLayoutAttributeNotAnAttribute
                                                multiplier:1.0f
                                                  constant:self.frame.size.height]];

制約が追加されました。これはNSLogで確認できます。

"<NSLayoutConstraint:0x100605cc0 H:[ITControlPanelChildView:0x100616eb0(269)]>",
"<NSLayoutConstraint:0x100614410 V:[ITControlPanelChildView:0x100616eb0(317)]>"

最後に、を使用して制約を変更しようとすると[constraint setConstant:somethingDifferent];、次の例外が発生します。

Unable to simultaneously satisfy constraints:
(
    "<NSLayoutConstraint:0x10192fcb0 V:[ITControlPanelChildView:0x10192e4f0(100)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x10053ff10 h=--& v=&-- V:[ITControlPanelChildView:0x10192e4f0(317)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x10192fcb0 V:[ITControlPanelChildView:0x10192e4f0(100)]>

これはまさに私が変更しようとしている制約です。なぜこれが起こっているのか誰かが私に説明できますか?


編集

が自動的に追加されることを読みました。NSAutoresizingMaskLayoutConstraintこれを設定すると無効にできます[self setTranslatesAutoresizingMaskIntoConstraints:NO];

無効にすると動作します。

NSAutoresizingMaskLayoutConstraint作成されたものにアクセスできればさらに良いでしょう。誰かがこれがどのように機能するか知っていますか?

4

2 に答える 2

8

含めていないログメッセージの残りの部分に示されているように、不要または不要な自動サイズ変更の制約があります。

サブビューを追加するときに、これらを削除できます。上記で使用している方法で、次の行を追加するだけです。

self.translatesAutoresizingMaskIntoConstraints = NO;

別のペン先でビューを作成している場合でも、そのサイズはどこから取得されますか?アウトレットを作成できるサイズの制約はすでにありませんか?

于 2012-12-19T18:01:31.780 に答える
1

私はこの問題を2回経験しました。

私は、 Hillegass&PrebleによるMac OSX4thEdのCocoaプログラミングで説明されている手法を使用しました。この本は、NSBoxをビューコンテナとして使用し、コードを使用してビューをそれに切り替えることを推奨しています。この本には、切り替えたばかりのビューを保持するために、外部の包含ウィンドウのサイズを手動で変更するための便利なコードも含まれています。

彼らのテクニックを初めて試したとき、私はこの例外を受け取りました:

2013-01-05 22:56:05.103 MyApp[17717:303] Unable to simultaneously satisfy constraints:
(
    "<NSAutoresizingMaskLayoutConstraint:0x100141330 h=--& v=--& H:[NSView:0x10012fdf0(4)]>",
"<NSLayoutConstraint:0x1001316c0 H:[NSScrollView:0x100123ff0]-(NSSpace(20))-|   (Names: '|':NSView:0x10012fdf0 )>",
"<NSLayoutConstraint:0x1001315d0 H:|-(NSSpace(20))-[NSScrollView:0x100123ff0]   (Names: '|':NSView:0x10012fdf0 )>")

Will attempt to recover by breaking constraint 

苛立たしいことに、UIをリファクタリングする必要があり、再構築されたバージョン(単純なウィンドウではなくNSDocumentに基づく)で、同じ問題が再び発生しました。

サブビューでtranslatesAutoResizingConstraintsをNOに設定すると、正しくレイアウトされません。しかし、これらのサブビューは複雑であるため、私のウィンドウがレイアウトされていないため、解決策にはなりません。ただし、それによって例外がスローされるのを防ぐことができます。

トップレベルのNSDocumentベースのウィンドウXIBでAutoLayoutをオフにすると、例外もスローされなくなります。しかし、トップレベルの要素のレイアウトが間違っており、ボックスのサイズが正しくありません。これはそれほど複雑ではないので、手動ですべてをレイアウトすることはできませんでした。

奇妙なことに、UIの最初のバージョンでは、スローなしで動作します。最初のバージョンでは、トップレベルビューとすべてのサブビューに自動レイアウトが設定されています。

私は一生の間、一方の設定がオンになっているのに、もう一方の設定がオンになっていないことを見つけることができません。ビューをドキュメントベースのバージョンにスワップするためにウィンドウバージョンで機能するのとまったく同じコードを貼り付け、すべての設定をコントロールチェックすることでコントロールを通過しました。

この問題を最初に修正した記憶は、XIBでAutoLayoutをオフにしていたことですが、2回目の修正を試みているところ、AutoLayoutがオンになっていて、正常に動作しています。

最初のバージョンは機能します-2番目のバージョンは機能しません。私が考えることができる唯一のことは、NSDocumentまたは他の何かの何かが問題を引き起こしているということです。

ただし、ケース2で修正する方法を見つけました。ビューコンテナとして使用されるNSBoxの[AutoResizesSubviews]チェックボックスをオフにします。

UIの最初のバージョン(そのチェックボックスセットで正常に機能する)でこれが必要ない理由は謎です。

とにかく-それが他の誰かを助ける場合に備えて、ここに文書化されています。

于 2013-01-05T13:25:00.243 に答える