実行時に特定のサブビューの自動レイアウトを無効にできますか?


104

フレームをプログラムで操作する必要があるビューがあります。これは、フレームの原点を操作することによってスーパービューの周りをスクロールおよびズームするコンテンツにラップする一種のドキュメントビューです。Autolayoutは実行時にこれと戦う。

自動レイアウトを無効にすることは、他のビューのレイアウトを処理するために合理的に使用できるため、完全に少し厳しいように見えます。私が望むのは、ある種の「null制約」のようです。

回答:


168

私も同じ問題を抱えていました。しかし、私はそれを解決しました。
はい、UIViewXcode 4.3以降でデフォルトで設定されているxibまたはストーリーボード全体に対して無効にする代わりに、特定のの実行時に自動レイアウトを無効にすることができます。

サブビューのフレームを設定する前translatesAutoresizingMaskIntoConstraintsYES、に設定します。

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);

2
これは、多くのビューを持ついくつかのより複雑なケースではやり過ぎのようです。これほど単純なものについては、これで問題ありません。
esh

@MuhammadAamirALiサブビューを削除してから再度追加すると、パフォーマンスが低下する可能性があります。より良いソリューションをアーカイブできますか?
Nhat Dinh 2014年

2
@DinhNhat答えを明確にしました。サブビューを削除して再度追加する必要はありません。
Leandros 2014年

5
「制約を同時に満たすことができない」という警告が表示されます。
NSPratik 2015

1
あなたは私の日を保存しました... translatesAutoresizingMaskIntoConstraints ...このシェイキングヘッドの
Tintenklecks

50

Autolayoutが実行時にフレーム設定の一部を上書きするという同様の問題がありました(場合によっては、新しいビューコントローラーを押す動的ビューがありました...押してから[戻る]を押すと、初期ビューがリセットされます)。

これを回避するにviewDidLayoutSubviewsは、View Controllerに操作コードを配置しました。これは、mojoが呼び出された後、viewDidAppearの前に呼び出されるように見えるため、ユーザーは賢明ではありません。


1
self.navigationItem.titleViewでは機能しません。それでもフレームの変更は考慮されません。
Henrik Erlandsson

1
タイトルビューのフレームをいじくり回そうとしている場合は、コンテナービュー内に配置して、ナビゲーションビューのカスタムビューとしてコンテナービューを追加します。
jmstone617 2013

2
これも私にとってはうまくいきました。この回避策を発見する前に、2h:22mをことわざの壁に頭をぶつけて無駄にしました。
TMc、2014年

ありがとう。私はこの問題に苦労して2日目ですが、今はうまくいきます!
apostolov

28

おそらくに設定translatesAutoresizingMaskIntoConstraintsするだけでYES(そのビューに影響を与える追加の制約を追加しないで)、自動レイアウトシステムと競合することなくフレームを設定できます。


17

iOS 8では、NSLayoutConstraintをアクティブにするかどうかを設定できます。したがって、インターフェイスビルダーを使用している場合は、すべての制約をOutletCollectionに追加してから、以下を使用してアクティブ化または非アクティブ化します。

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

ここで使用している特定のアプリケーションは、縦長モードと横長モードで異なる制約があり、デバイスの回転に基づいてアクティブ化/非アクティブ化します。つまり、両方の方向のインターフェイスビルダーですべて複雑なレイアウト変更を作成でき、詳細な自動レイアウトコードがなくても自動レイアウトを使用できます。

または、removeConstraintsおよびaddConstraintsを使用してアクティブ化/非アクティブ化できます。


このような古い質問をハイジャックして申し訳ありませんが、最初にさまざまなレイアウトのレイアウト制約をどのように追加できたのでしょうか。制約を有効/無効にするためのインターフェイスビルダー内のオプションが見つからないようです。それとも、両方のレイアウトに制約を追加して、無効な(オーバーライド)制約について不平を言っているインターフェイスビルダーを無視しただけですか?
Malte

さてあなたは、サイズクラス使用することによってそれを行うことができます:developer.apple.com/library/ios/recipes/...を、私はあまりにも、サイズクラスは完全にはサポートしていないiOSの7のiOS 7を支持したため、私は、このようにそれを行うことができませんでした。競合する制約の優先度を下げることでそれを実現しました。理想的ではありませんが、警告を防ぎます。私は....これは私はとにかくそれをやった方法だと思う
bandejapaisa

9

これが他の人に役立つかどうかはわかりませんが、これを便利にするためのカテゴリを作成しました。

UIView + DisableAutolayoutTemporarily.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView + DisableAutolayoutTemporarily.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

私はそれを次のように使用します:

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

それが役に立てば幸い。


鮮やかさ !コードの修正バージョンを使用して、任意のUIViewの単純な「hideControl」関数を記述しました。基本的に、UIViewの高さを0に設定しますが、重要なことに、AutoLayoutに適切に処理させるためにコードを使用します(「someView.hidden = TRUE」を使用する場合とは異なります)。そのため、非表示コントロールの下に表示され、それに垂直方向の間隔がリンクされていたコントロールは、以前は非表示ビューが表示されていたギャップを埋めるために画面上にシフトします。
Mike Gledhill、2014

6

xib / storyboardで必要なUIViewのユーザー定義ランタイム属性でtranslatesAutoresizingMaskIntoConstraintsタイプBoolean値はいを設定できます。


2
  • 4.5でプロジェクトを開く
  • ストーリーボードを選択
  • ファイルインスペクターを開く
  • Interface Builder Documentで、「Use Autolayout」のチェックを外します

一部のビューで自動レイアウトを使用する場合は、複数のストーリーボードに分割できます。


10
これにより、ストーリーボード/ペン先全体の自動レイアウトが無効になります。私が探していたのは、ストーリーボード/ nib内の特定のサブビューがautolayoutを使用せず、残りを指定されたストーリーボード/ nibのままにする方法(理想的にはプログラム)でした。
ひどい

複数のストーリーボードを使用して、必要に応じてautolayoutあり/なしのストーリーボードを呼び出すことができます。DetailViewController * dvController = [sb instantiateViewControllerWithIdentifier:entry.viewName];
マイクボビット

1

私にとって、それはプログラムでサブビューを作成するのに役立ちました、私の場合、自動レイアウトは中心を中心に回転する必要のあるビューを混乱させていましたが、このビューをプログラムで作成すると、それは機能しました。


1

私の見解では、ラベルとテキストがありました。ラベルにはパンジェスチャーがありました。ドラッグ中にラベルが動き回ります。しかし、テキストボックスキーボードを使用すると、ラベルはその位置を自動レイアウトで定義された元の場所にリセットします。この問題は、次のラベルをすばやく追加すると解決しました。これをviewWillAppearに追加しましたが、ターゲットフィールドにアクセスできるほとんどの場所に追加できます。

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

0

これは、ストーリーボードまたはxibファイルのないプロジェクトで発生しました。すべて100%コード。下部に広告バナーがあり、ビュー境界が広告バナーで止まるようにしたかった。ロード後、ビューは自動的にサイズを変更します。このページのすべての解決策を試しましたが、どれもうまくいきませんでした。

高さを短くしてサブビューを作成し、コントローラーのメインビューに配置しました。次に、すべてのコンテンツがサブビュー内に移動しました。それは、穀物に反するようなことをすることなく、問題を非常に簡単に解決しました。

ウィンドウを埋める通常のサイズではないビューが必要な場合は、そのためにサブビューを使用する必要があると考えています。


0

自動レイアウトで開始されたプロジェクトに参加したという同様のシナリオに遭遇しましたが、いくつかのビューを動的に調整する必要がありました。これが私のために働いたものです:

  1. インターフェイスビルダーでレイアウトされたビューまたはコンポーネントはありません。

  2. 純粋にプログラム的にalloc / initから始めて、適切にフレームを設定するビューを追加します。

  3. できました。


0

自動レイアウトを無効にする代わりに、置き換えるフレームで新しい制約を計算します。それは私には適切な方法であるように見えます。制約に依存するコンポーネントを調整する場合は、それに応じて調整します。

たとえば、2つのビュー(myViewとotherView)の間に垂直方向の制約0があり、パンジェスチャーまたはmyViewの高さを調整するものがある場合、調整した値で制約を再計算できます。

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];

0

自動レイアウトを使用している方は、こちらの解決策をご覧ください。@IBOutlet調整したい制約のを作成し、その定数を変更する必要があります。


-16

xibファイルの場合:

  1. .xibファイルを選択します
  2. 「ファイルの所有者」を選択します
  3. ユーティリティを表示
  4. 「ファイルインスペクタ」をクリックします
  5. 「Interface Builder Document」の下で、「Use Autolayout」を無効にします。

1
いいえ、それはxib全体の自動レイアウトを無効にします。私が探していたのは、自動レイアウトシステムから特定のサブビューを1つだけ取り出す方法です。
ひどい
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.