いくつかの制約を介して画面に配置されるUIViewがあります。一部の制約はスーパービューによって所有され、その他の制約は他の祖先によって所有されます(たとえば、UIViewControllerのviewプロパティ)。
これらの古い制約をすべて削除し、新しい制約を使用して新しい場所に配置したいと思います。
すべての制約に対してIBOutletを作成せず、どのビューがその制約を所有しているかを覚えておく必要なしに、これを行うにはどうすればよいですか?
詳述すると、単純なアプローチは、制約ごとにIBOutletsの束を作成し、次のようなコードを呼び出すことです。
[viewA removeConstraint:self.myViewsLeftConstraint];
[viewB removeConstraint:self.myViewsTopConstraint];
[viewB removeConstraint:self.myViewsBottomConstraint];
[self.view removeConstraint:self.myViewsRightConstraint];
このコードの問題は、最も単純な場合でも、2つのIBOutletを作成する必要があることです。複雑なレイアウトの場合、これは4つまたは8つの必要なIBOutletsに簡単に到達する可能性があります。さらに、制約を削除するための呼び出しが適切なビューで呼び出されていることを確認する必要があります。たとえば、myViewsLeftConstraint
がによって所有されていると想像してくださいviewA
。誤って電話をかけても[self.view removeConstraint:self.myViewsLeftConstraint]
、何も起こりません。
注:メソッドconstraintsAffectingLayoutForAxisは有望に見えますが、デバッグのみを目的としています。
アップデート:私は契約を受けています回答の多くはself.constraints
、self.superview.constraints
これらの、またはいくつかの変種。これらのメソッドは、ビューに影響を与える制約ではなく、ビューが所有する制約のみを返すため、これらのソリューションは機能しません。
これらのソリューションの問題を明確にするために、次のビュー階層を検討してください。
- 祖父
- お父さん
- 私
- 息子
- 娘
- 兄
- 私
- おじさん
- お父さん
ここで、次の制約を作成し、それらを常に最も近い共通の祖先にアタッチするとします。
- C0:私:息子と同じトップ(私が所有)
- C1:私:幅= 100(私が所有)
- C2:私:ブラザーと同じ高さ(父が所有)
- C3:私:おじさんと同じトップ(祖父が所有)
- C4:私:祖父と同じ左(祖父が所有)
- C5:兄弟:父と同じ左(父が所有)
- C6:おじさん:おじいさんと同じ左(おじいさんが所有)
- C7:息子:娘と同じ左(私が所有)
ここで、に影響を与えるすべての制約を削除したいとしますMe
。適切な解決策は削除する必要が[C0,C1,C2,C3,C4]
あり、他には何もありません。
self.constraints
(selfがMeである場合)を使用[C0,C1,C7]
すると、Meが所有する唯一の制約であるため、が取得されます。明らかに、これが欠落しているため、これを削除するだけでは十分ではありません[C2,C3,C4]
。さらに、C7
不必要に取り外しています。
私がself.superview.constraints
(自己が私である場合)を使用する場合[C2,C5]
、それらは父が所有する制約であるため、私は取得します。とC5
はまったく関係がないため、明らかにこれらすべてを削除することはできませんMe
。
を使用するとgrandfather.constraints
、取得し[C3,C4,C6]
ます。繰り返しますが、そのC6
ままにしておく必要があるため、これらすべてを削除することはできません。
強引なアプローチは、ビューの祖先(それ自体を含む)のそれぞれをループし、ビュー自体であるかどうfirstItem
かsecondItem
を確認することです。その場合は、その制約を削除します。これにより、正しい解が返され[C0,C1,C2,C3,C4]
、が返され、それらの制約のみが返されます。
ただし、祖先のリスト全体をループするよりも、より洗練されたソリューションがあることを望んでいます。