Appleは、次のコードを使用して、iPadまたはiPhone/iPod Touchで実行されているかどうかを検出することをお勧めします。
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// The device is an iPad running iPhone 3.2 or later.
// [for example, load appropriate iPad nib file]
}
else {
// The device is an iPhone or iPod touch.
// [for example, load appropriate iPhone nib file]
}
問題は、UI_USER_INTERFACE_IDIOM()およびUIUserInterfaceIdiomPadが3.2より前のSDKで定義されていないことです。これはそのような機能の目的を完全に無効にするようです。これらは、コンパイルしてiPhone OS 3.2でのみ実行できます(iPhone OS 3.2はiPadでのみ実行できます)。したがって、UI_USER_INTERFACE_IDIOM()を使用できる場合、結果は常にiPadを示すことになります。
IPhoneにバインドされたユニバーサルアプリのコードをテストするためにこのコードとターゲットOS 3.1.3(最新のiPhone/iPod Touch OS)を含めると、シンボルが3.1.3以前で定義されていないため、コンパイラエラーが発生します。 、iPhoneシミュレータ3.1.3用にコンパイルする場合。
これがランタイムデバイス検出へのApple推奨のアプローチである場合、何が問題ですか?この方法でデバイスを検出することに成功した人はいますか?
コードを3.1.3と3.2の両方でコンパイルするためにこれを行います。
BOOL iPad = NO;
#ifdef UI_USER_INTERFACE_IDIOM
iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#endif
if (iPad) {
// iPad specific code here
} else {
// iPhone/iPod specific code here
}
私もここで簡単なブログ投稿を書きました: http://www.programbles.com/2010/04/03/compiling-conditional-code-in-universal-iphone-ipad-applications/
これは私が使用するものです:
- (BOOL) amIAnIPad {
#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)
if ([[UIDevice currentDevice] respondsToSelector: @selector(userInterfaceIdiom)])
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
#endif
return NO;
}
これは条件付きでコンパイルされるため、3.0 sim用にビルドできます。次に、UIDeviceクラスがセレクターに応答するかどうかを確認します。これらのいずれかが失敗した場合、それはiPadではありません。
これがruntimeデバイス検出へのApple推奨のアプローチである場合、何が間違っていますか?この方法でデバイスを検出することに成功した人はいますか?
これはruntime検出のソリューションです:
#define isIPhone (![[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] || [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
その後、コード内の任意の場所で簡単にテストできます。
if (isIPhone) { ... }
これと#if/#ifdefの使用の違いは、これはランタイムテストであるのに対し、#ifはコンパイル時テストです。
この場合、どのOSバージョンでも正確なものを使用できるので、ランタイムテストの方が良いと思います。コンパイル時チェックを使用する場合は、OSバージョンごとに異なる実行可能ファイルを作成する必要があります。
問題がコンパイル時のエラーである場合は、SDKの最新バージョンに対してコンパイルする必要があります( iOSで弱リンクフレームワークにアクセスする方法 も参照)。
私が使用するコンパイラベースのものの代わりに:
- (BOOL)deviceIsAnIPad {
if ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)])
//We can test if it's an iPad. Running iOS3.2+
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
return YES; //is an iPad
else
return NO; //is an iPhone
else
return NO; //does not respond to selector, therefore must be < iOS3.2, therefore is an iPhone
}
答えは、iPhoneでコードを実行しないでくださいsimulator 3.1.3以前。常に3.2 SDKでコンパイルします。 iPhoneシミュレーター3.2を使用すると、iPadシミュレーターを入手できます。または、iPhoneデバイス3.2用にコンパイルして、アプリを電話に置いてテストします。
3.2 SDKに対してコンパイルして3.1.3以前のシミュレータを使用する方法はありません。
これを使用して宣言する
#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD false
#endif
次に、以下のようにチェックを使用します
#define DetailLabel_PosX (IS_IPAD ? 200 : 160)
Iphone 5をチェックするための定義もあります
#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
#define IOS_OLDER_THAN_6 ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0 )
#define IOS_NEWER_OR_EQUAL_TO_6 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0 )
UI_USER_INTERFACE_IDIOM()およびUIUserInterfaceIdiomPadはiOS3.2以降で使用できます。重要な部分は「上向き」です。承知しました。 iOS3.2はiPad専用ですが、iOS4.0以降はiPhoneとiPadの両方で動作するため、このチェックは思ったほど無意味ではありません。
これはそのような機能の目的を完全に無効にするようです。これらは、コンパイルしてiPhone OS 3.2でのみ実行できます(iPhone OS 3.2はiPadでのみ実行できます)。したがって、UI_USER_INTERFACE_IDIOM()を使用できる場合、結果は常にiPadを示すことになります。
これは完全に間違っています。 3.2のベースSDKではcompiledにすることができますが、デプロイメントターゲットを適切に設定すれば、どのOSでもrunにすることができます。