IOSの以前のバージョンの古いデバイスとの互換性を提供しながら、iOS 6の新しい自動レイアウト機能を利用する最良の方法は何ですか?
自動レイアウトは、各.storyboardまたは.xibファイルで有効または無効にできます。特定のファイルを選択し、Xcodeのファイルインスペクターを使用して「自動レイアウトを使用」プロパティを変更するだけです。
デプロイメントターゲットを6.0より前のiOSバージョンに設定して自動レイアウト対応のインターフェイスファイルを使用すると、コンパイルエラーが発生します。例:
MainStoryboard.storyboard:3のエラー:6.0より前のiOSバージョンでの自動レイアウト
プロジェクトで自動レイアウトを使用し、iOS4-5との互換性を維持するためのオプションの1つは、2つの targets を作成することです。1つはデプロイメントターゲットiOS 6.0用、もう1つは以前のiOSバージョン用です。
ストーリーボードとXIBファイルのそれぞれに対して2つのバージョンを作成し、6.0ターゲットで有効になっている自動レイアウトとレガシーターゲットで有効な自動レイアウトを使用できます。例:
次に、MainStoryBoardAutoSizeをiOS6ターゲットのビルドフェーズに追加し、他のファイルをiOS4ターゲットに追加します。複数のターゲットの使用の詳細については、こちらをご覧ください こちら 。
編集: marchinram's answer 指摘するように、コードからストーリーボードファイルをロードし、Xcodeの「メインストーリーボード」設定を使用して初期ストーリーボードを設定しない場合、単一のターゲットを使用できます。
私にとっては、複数のターゲットとインターフェースファイルを維持するために追加される複雑さのコストが、自動レイアウトを使用する利点を上回るようです。いくつかの特別な場合を除いて、iOS4-5との互換性が必要な場合は、従来の単純な自動サイズ変更(またはコードのlayoutSubViews)を排他的に使用することをお勧めします。
本当に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つのターゲットを持つこともうまくいきますが、私にとってはやり過ぎのようです
レイアウトの違いが大きくない場合は、 Springs and Struts を使用して要素を配置する方がはるかに簡単です。
@marchinramの1つのターゲットアイデアに触発され、これが最終的に思いついたソリューションです。ストラットアンドスプリング用とオートレイアウト用の2つのストーリーボード。ターゲットの概要では、自動レイアウトストーリーボードをデフォルトとして設定しました。次に、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に設定し、自動レイアウトストーリーボードの展開ターゲットをProject SDK(iOS 6.0)に設定しました。
WillFinishLaunchingWithOptions:でストーリーボードのデフォルトがロードされる前に切り替えを実行したかったのですが、その結果、「NSInvalidUnarchiveOperationException」が発生しました。理由は、「NSLayoutConstraintという名前のクラスをインスタンス化できませんでした」.
RRAutoLayoutを使用してみてください。 https://github.com/RolandasRazma/RRAutoLayout iOS5 AutoLayoutバックポートはiOS5です。
XibsのメインビューのサイズをFreeformに設定し、自動サイズ調整を使用するとうまくいきます。ビューの問題のためにコードに混乱はありません。