web-dev-qa-db-ja.com

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

私はフレームをプログラムで操作する必要があるビューを持っています-それはコンテンツにラップする一種のドキュメントビューで、フレームのOriginを操作することでスーパービューの周りをスクロールしてズームします。自動レイアウトは、実行時にこれと戦います。

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

101
terriblememory

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

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

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

Autolayoutが実行時にフレーム設定の一部をオーバーライドするという同様の問題がありました(場合によっては、新しいView Controllerをプッシュする動的ビューがありました...押してからBackを押すと初期ビューがリセットされました)。

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

49
jmstone617

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

26
Jon Hull

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

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

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

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

17
bandejapaisa

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

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];
}];

それが役に立てば幸い。

8
michaelsnowden

Xib /ストーリーボードで必要なUIViewのユーザー定義のランタイム属性で、translatesAutoresizingMaskIntoConstraints type Boolean、Value Yesを設定できます。

6
renaun

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

1
Andrespch

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

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true
1
Big D
  • 4.5でプロジェクトを開く
  • ストーリーボードを選択
  • ファイルインスペクターを開きます
  • Interface Builder Documentで「Use Autolayout」のチェックを外します

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

1
Mike Bobbitt

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

  1. インターフェイスビルダーでビューまたはコンポーネントをレイアウトしないでください。

  2. ビューを純粋にプログラムで追加し、alloc/initで開始し、フレームを適切に設定します。

  3. できた.

0
Yup.

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

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

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

0
RandallTo

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

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

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

自動レイアウトを使用している方は、私のソリューション here をご覧ください。調整する制約の@IBOutletを作成してから、定数を変更する必要があります。

0
Mike