UIViewに影響を与えるすべての制約を削除します
いくつかの制約を介して画面に配置される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]、が返され、それらの制約のみが返されます。 ただし、祖先のリスト全体をループするよりも、より洗練されたソリューションがあることを望んでいます。