2012-11-14 9 views
46

UIViewにはUIImageViewが埋め込まれています。私のアプリ全体はAutoLayoutを使用していますが、UIImageViewの場合はconstraintsを削除します。 Xcode私はconstraintsを削除できません。特定のオブジェクトに対して無効にする方法はありますか?ゼロに設定してください。特定のオブジェクトの自動レイアウト制約を削除する

+0

制約を削除すると、イメージビューはどのように表示されますか?レイアウトエンジンは、どのように配置するのかをどのように認識しますか?あなたは、全体像を明白にレイアウトするのに十分な制約情報を持たなければなりません。実際に何を達成しようとしていますか? – jrturton

+0

ジェスチャーで画像ビューのサイズを変更したいと思います。自動レイアウトの制約により、ピンチジェスチャーで画像ビューを小さくすることはできません。 – Eric

+0

特定のXIBファイルの場合は、クリアするだけです。 ** autolayoutをオフにする(つまり、 "Constraints thingyを削除する")にはShowFileInspectorをクリックし、単に "autolayout"のチェックを外してください。 xib上の各アイテムは、「古い」スタイル(「スティッキー・アロー」など)のように機能するようになります。 – Fattie

答えて

86

私はプログラム的制約を取り除くために使用するもの

... Xcodeの自動レイアウトは、あなたが特定の何かをしたい場合に使用する恐ろしいです同意:

[detailsPhotoView removeConstraints:detailsPhotoView.constraints]; 
+0

ありがとう、これは働いた。ビューからすべての制約を削除し、ビジュアルフォーマット言語を使用して再設定しました。上記のコードはあなた自身を指定する前に制約を削除する必要があります。それ以外の場合はxcodeがエラーを返します –

+0

UIImageViewから制約を削除しようとしている場合、コードでそのビューを追加してください。 IBoutletを使用しないでください。あなたのsetFrameコードには何の効果もないようです。私はちょうどこのくそに入った。 –

6

あなたはは制約がありませんないことができます - あなたはあなた自動レイアウトを使用してレイアウトされているサイズ変更可能なビューを作成することができます明確にサイズや位置ごとのビュー

の場所に十分な制約を持っている必要があります。

たとえば、画像ビューの中心をそのスーパービューの中心に水平および垂直にピン止めするなど、位置決めの制約を作成できます。

また、サイズの制約を水平および垂直に作成することもできます。これを行う方法は私の答えhereを参照してください。これらの2つの制約へのアウトレットを作成します(インタフェースビルダーを使用する場合)。特定の数値の高さと幅の制​​約を持つことができます。または、乗数を使用して固定のアスペクト比を作成できます。

ピンチジェスチャーに応答して、2つのサイズの制約の.constantプロパティを調整し、setNeedsLayoutを呼び出すことができます。これにより、中央を固定したままでイメージビューのサイズが変更されます。

上記の固定アスペクト比の提案を行う場合、実際には制約を使用してビューのサイズを変更するのは、フレームを設定するよりはるかに簡単です。

+0

このコンテナUIView内に何かを固定したくないです。私はimageView(UIView内の1つ)が何かを固定することやサイズの制約を受けることなく、挟まれたり、動かされたり、パンされたりすることができるようにしたい。私はそれのためにどんな定数を設定しますか?私はすべての制約を取り除くという私の考えをすぐには達成できないようです。 – Eric

+0

サイズを変更するだけでなく、サイズを変更したい場合は、上記のサイズ制約を記述するのと同じ方法でコードで変更できるコンセントもある位置決め制約が必要です。あなたには制約がありません - すべてのビューのサイズと位置を明白に決めるためには、十分な制約がなければなりません。 – jrturton

+0

これを編集に追加して回答しますか?すべてのビューのサイズと位置を明確にするための制約が十分にある必要があります。それから私はそれを受け入れるでしょう。 – Eric

8

ここでは二つの別個の問題があります。

  1. そのレイアウトが制約によって処理されるときにUIImageViewは、パンニングおよび/またはサイズを変更できるようにする方法制約
  2. せずにセットアップにUIImageViewをXcodeの使用方法。

(1)に関して、jturtonは正しいです。 Xcode内で自動レイアウトを有効にしている限り、Xcodeはビューのサイズと場所を一意に決定するのに十分な制約があることを保証/要求します。

(レイアウトインスペクタで青色で表示される「ユーザ制約」を使用して)Xcodeに手作業で十分な制約を指定していない場合、Xcodeは推測する新しい制約を追加しますレイアウトを決定するための制約。

UIImageViewに制約がない場合、そのレイアウトは決定されないため、Xcodeで設定することはできません。これを修正するには、削除するすべての制約にIBOutletを設定し、次にUIViewのawakeFromNib:またはUIViewControllerのviewDidLoadでXcodeを使用してremoveConstraints:を呼び出して手動で制約を削除します。

しかし、あなたのUIImageViewのレイアウトは未定です。この時点で、UIImageViewの移動とサイズ変更を可能にする新しい制約を手動で追加する必要があります。これにより、質問(2)が表示されます。そのレイアウトの制約によって決定されたビューを移動&サイズを変更する方法(2)について

、答えはピンチに&パンジェスチャーを検出するために、いつものようにセットアップジェスチャー認識装置にあるが、代わりにこれらのジェスチャー認識装置はsetFrameを呼び出す:へUIImageViewのフレームを決定するNSLayoutConstraintのconstantパラメータを変更してからlayoutIfNeeded:を呼び出すと、レイアウトシステムは変更された制約を直ちに新しいフレームに変換します。

たとえば、使い慣れたsetFrame:とよく似たレイアウト制約のセットを使ってUIImageViewを操作したいとします。その場合、Xcodeで設定された制約を削除した後、ビューに幅、高さ、およびスーパービューの上端と左端からのスペースを指定する制約を追加できます。次に、パンジェスチャ認識プログラムのアクションハンドラは、単にペースメーカジェスチャ認識プログラムの定数パラメータを更新するだけで、ピンチジェスチャ認識プログラムは高さと幅の制​​約の定数パラメータを更新することができます。

(2)を実行するもう1つの方法は、フードの下では同じですが、実際にはより簡単ですが、translatesAutoresizingMaskIntoConstraints=YESを設定することです。これは2つのことを行います。自動レイアウトシステムは、ビューの自動化マスクに基づいて、ビューのスーパービュー内に自動的に制約を生成します。第二に - 決定的に!レイアウトシステムが自動的にsetFrame:への呼び出しをこれらの制約の変更に変換します。

+2

制約を削除するにはPITAが1つあります。制約をホストするビューから制約を削除する必要があります。例えば。スクロールビュー内にイメージビューとイメージビューがあり、それらの間に制約がある場合は、スクロールビューをホストするスクロールです。制約はイメージビューの 'constraints'プロパティには存在しません。イメージビューで' removeConstraint: 'を呼び出すことは黙って無視され、制約自体からホストビューを取得する方法はありません。したがって、スクロールビューと制約の両方のアウトレットが必要です。具体的には '[self.scrollView removeConstraint:self.constraint]'を呼び出す必要があります。アー! –

24

XCodeの5で編集中のオプションがあります制約 'ビルド時に削除'。これを有効にすると、実行時に制約が自動的に削除されます。特定の制約を必要としない場合、Interface Builderを幸せに保つためのオプションがあります。

+0

ベストアンサー、短く正確です。 – Borzh

+0

XCode 6では、このオプションはプレースホルダに設定されたオプションでイントリンシックサイズと呼ばれるようになりました。 – ChrisStillwell

5

あなたは

[yourElement removeFromSuperview]; 

を呼び出してから、yourElementからすべての制約を削除し、ビューに戻って、それを追加する

[yourSuperview addSubview:yourElement]; 

を呼び出すことができます。

それはあなたがUIViewのカテゴリまたは延長のようなものの上に上記を行っている場合、あなたはスーパービューから削除する前に、ビューのスーパーへの参照を保存する必要があることを言及する価値がある:あなたがまた必要になる場合があります

var theSuperview = self.superview 
self.removeFromSuperview() 
theSuperview?.addSubview(self) 

スーパービューから削除すると潜在的に参照を失う可能性があるため、あなたのElementを弱くするのではなく強くします。

+0

私はremoveConstraintsメソッドに従わないカスタムオブジェクトobject.viewを持っています。これは素晴らしいことを解決しました。私が望んでいたのと全く同じように、プログラム上の警告と振る舞いは定義されていません。ありがとうございました! –

4

単に階層からビューを削除する場合は、[theView removeFromSuperview]を呼び出します。それに影響を与えるすべての制約も削除されます。

が削除されたビューを元に戻すこともできます。

これを達成するために、私はUIViewに次のカテゴリを使用します。ビューvから最終的なコンテナビューc(通常はビューコントローラのルートビュー)にビュー階層を移動し、vの外部にある制約を削除します。これらは、vの子にのみ影響する制約ではなく、兄弟である制約がvになります。 vを非表示にすることができます。

-(NSArray*) stealExternalConstraintsUpToView: (UIView*) superview 
{ 
    NSMutableArray *const constraints = [NSMutableArray new]; 

    UIView *searchView = self; 
    while(searchView.superview && searchView!= superview) 
    { 
     searchView = searchView.superview; 

     NSArray *const affectingConstraints = 
     [searchView.constraints filteredArrayUsingPredicate: 
     [NSPredicate predicateWithBlock:^BOOL(NSLayoutConstraint *constraint, NSDictionary *bindings) 
      { 
       return constraint.firstItem == self || constraint.secondItem == self; 
      }]]; 

     [searchView removeConstraints: affectingConstraints]; 
     [constraints addObjectsFromArray: affectingConstraints]; 
    } 

    return constraints; 
} 

方法は、あなたが戻って制約を追加することができ、後になるようにあなたがどこかに保つことができる配列で削除制約をバックに渡します。

は少しこのようにそれを使用して...

NSArray *const removedConstraints = [viewToHide stealExternalConstraintsUpToView: self.view]; 
[viewToHide setHidden: YES]; 

そして後に、バック制約を置きます。

iOS 8では、制約をどこに置くべきかについて考える必要はありません。これをちょうど使用してください...

以前のバージョンのiOSでは、制約をどこに追加するかについて懸念する必要はありません。コントローラーのself.viewにスローします。提供される制約は、影響を受けるすべてのビューのスーパービューであり、動作します。

[self.view addConstraints: removedConstraints]; 
[viewToHide setHidden: NO]; 
+0

activateConstraintsはiOS 8以降利用可能です。 –

+0

@ b.zdybowicz - ありがとう、それを明示的にするように更新しました。誰でも編集を行うことができます。 – Benjohn

関連する問題