iOS 5との下位互換性を維持しながら、iOS 6で自動レイアウトを有効にする


153

以前のバージョンのiOSで古いデバイスとの互換性を維持しながら、iOS 6の新しい自動レイアウト機能を利用する最良の方法は何ですか?


+1。これを理解できる場所はどこですか?どんな手掛かり ?
Janak Nirmal 2012

@Jennisまだです。iOS 6は明日正式にリリースされます(2012年9月19日)。うまくいけば、それは主題に関するいくつかの追加のドキュメントを含みます。
sglantz 2012

まだ何も見つかりません。探究心は知りたいです!
ベンクリーガー2012

それは可能ではないと思います。iOS4ではストーリーボードは不可能でした。
レオナタン

2つのnibファイルを提供する以外に、それがどのように可能になるかはわかりません。しかし、私はあなたに同意します。
レオナタン

回答:


120

自動レイアウトは、各.storyboardファイルまたは.xibファイルで有効または無効にできます。特定のファイルを選択し、Xcodeのファイルインスペクタを使用して[Autolayoutを使用]プロパティを変更するだけです。

ファイルインスペクターのautolayoutプロパティ

展開ターゲットが6.0より前のiOSバージョンに設定されたautolayout対応のインターフェースファイルを使用すると、コンパイルエラーが発生します。例:

MainStoryboard.storyboard:3のエラー:6.0より前のiOSバージョンでの自動レイアウト

プロジェクトでautolayoutを使用し、iOS4-5との互換性を維持するためのオプションの1つは、2つのターゲットを作成することです。1つはデプロイメントターゲットiOS 6.0用で、もう1つは以前のiOSバージョン用です。例:

ここに画像の説明を入力してください

ストーリーボードとXIBファイルのそれぞれに2つのバージョンを作成し、6.0ターゲットで有効になっているオートレイアウトとレガシーターゲットでもう1つを使用することができます。例:

ここに画像の説明を入力してください

次に、MainStoryBoardAutoSizeをiOS6ターゲットのビルドフェーズに追加し、他のファイルをiOS4ターゲットに追加します。複数のターゲットの使用について詳しくは、こちらをご覧ください

編集:marchinramの回答が指摘しているように、コードからストーリーボードファイルをロードし、Xcodeの「メインストーリーボード」設定を使用して初期ストーリーボードを設定しない場合、単一のターゲットを使用できます。

私にとっては、複数のターゲットとインターフェースファイルを維持するために追加される複雑さのコストが、自動レイアウトを使用するメリットを上回るようです。いくつかの特別な場合を除いて、iOS4-5の互換性が必要な場合は、通常の自動サイズ調整(またはコードのlayoutSubViews)のみを使用する方がはるかに良いでしょう。


29
自動レイアウトにはiOS 6以降が必要です。iOS 5では動作しません!投稿する前に申し立てを確認してください。iOS 5には、必要なAPI(クラスNSLayoutConstraintなど)がありません。あなたは私を信じていない場合、彼らはiOSの5で自動レイアウトを使用しようとすると、どのような他のユーザー体験をチェックアウト:stackoverflow.com/questions/11252057/...の stackoverflow.com/questions/11198981/...を
イムレKelényi

1
はい、私はあなたが正しいと思う私はいくつかのwwdcビデオでそれを聞いたと思います、しかし今私はそれをiOS 5.0デバイスでテストしてそれがクラッシュしました。私はこれらのビデオを調べて、どこでそれを聞いたのかチェックしますそれでもあなたは正しいですそれはiOS 5.0でクラッシュします
Asad Khan

@ImreKelényiこれをアプリストアにどのように送信しますか?私はこのプロセスにあまり詳しくありませんが、.appファイルの1つの圧縮アーカイブを送信すると思いました。2つのターゲットがあると、そのプロセスはまったく難しくなりますか?ありがとう。
クリスタル

47

本当に2つのターゲットが必要ですか?私はそれをこのように機能させています、ImreKelényiが言ったように2つのストーリーボードがあります.1つは自動レイアウトが有効で、もう1つは有効ではありません。アプリのデリゲートで、使用しているバージョンを確認し、適切なストーリーボードを選択します:

#import "AppDelegate.h"

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)

@interface AppDelegate ()
    @property (strong, nonatomic) UIViewController *initialViewController;
@end

@implementation AppDelegate

@synthesize window = _window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIStoryboard *mainStoryboard = nil;
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
        mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS6" bundle:nil];
    } else {
        mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS5" bundle:nil];
    }

    self.initialViewController = [mainStoryboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = self.initialViewController;
    [self.window makeKeyAndVisible];

    return YES;
}

@end

2つのターゲットを持つことも同様に機能しますが、私にはやり過ぎのようです


1
あなたが正しいです。これは、コードからストーリーボードをロードし、Xcodeでターゲットの「メインストーリーボード」設定を使用しない限り機能します。私の投稿からあなたの回答への参照を追加します。
ImreKelényi12年

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TOやりすぎです。iOS 6のみのクラスをnilに対してテストするだけです。developer.apple.com/library/mac/#documentation/developertools/…を
matt

ええ、良い点、私が最初に答えたとき、復元について本当に考えていなかった
marchinram 2013年

Ahem、willFinishLaunchingWithOptionsは使用しないでください-iOS 5.1でシミュレーターを実行しているときに、「キャッチされない例外 'NSInvalidUnarchiveOperationException'のためにアプリを終了しています。理由: 'NSLayoutConstraintという名前のクラスをインスタンス化できませんでした'」を受け取りました。この問題は、didFinishLaunchingWithOptionsでは発生しません。
Elise van Looij 2013年


3

@marchinramの1つのターゲットアイデアに触発された、これが私が最終的に思いついたソリューションです。2つのストーリーボード。1つは支柱とばね用、もう1つは自動レイアウト用です。ターゲットの概要では、autolayoutストーリーボードをデフォルトとして設定しました。次に、appDelegateで、6.0より前のstruts-and-springsストーリーボードをロードする必要があるかどうかを確認します。

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    Class cls = NSClassFromString (@"NSLayoutConstraint");
    if (cls == nil) {
        NSString *mainStoryboardName = nil;
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
            mainStoryboardName = @"MainStoryboard_iPad_StrutsAndSprings";
        } else {
            mainStoryboardName = @"MainStoryboard_iPhone_StrutsAndSprings";
        }
        UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:mainStoryboardName bundle:nil];

        UIViewController *initialViewController = [mainStoryboard instantiateInitialViewController];
        self.window.rootViewController = initialViewController;
        [self.window makeKeyAndVisible];
    }

また、struts-and-springsストーリーボードの展開ターゲットをiOS 5.1に設定し、autolayoutストーリーボードの展開ターゲットをProject SDK(iOS 6.0)に設定しました。

ストーリーボードのデフォルトが読み込まれる前に、willFinishLaunchingWithOptionsで切り替えを実行したかったのですが、結果は 'NSInvalidUnarchiveOperationException'になります。理由: '何を試してもNSLayoutConstraintという名前のクラスをインスタンス化できませんでした。



0

Xibsのメインビューのサイズをフリーフォームに設定し、自動サイズ設定を使用するとうまくいきます。ビューの問題のコードをいじる必要はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.