302

Xcode 4.5 GM にアップグレードしたところ、ストーリーボードのビュー コントローラーに「4" Retina」サイズを適用できるようになりました。

ここで、iPhone 4 と 5 の両方で動作するアプリケーションを作成したい場合、もちろんすべてのウィンドウを 2 回ビルドする必要がありますが、ユーザーが 3.5 インチまたは 4 インチの画面の iPhone を持っているかどうかを検出して、見る。

どうすればいいですか?

4

24 に答える 24

468

まず第一に、新しい画面に合わせてすべてのビューを再構築したり、異なる画面サイズに異なるビューを使用したりしないでください。

iOS の自動サイズ変更機能を使用して、ビューを調整し、任意の画面サイズに適応できるようにします。

それはそれほど難しいことではありません。それに関するドキュメントを読んでください。時間を大幅に節約できます。

iOS 6 では、これに関する新機能も提供されています。Apple Developer Web サイトのiOS 6 API 変更ログ
を 必ずお読みください。 そして、iOS 6 の新しいAutoLayout機能を確認してください。

そうは言っても、本当に iPhone 5 を検出する必要がある場合は、単純に画面サイズに頼ることができます。

[ [ UIScreen mainScreen ] bounds ].size.height

iPhone 5 の画面の高さは 568
です。これらすべてを単純化するためにマクロを想像できます。

#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

fabsH2CO3 のコメントで指摘されているように、浮動小数点を比較するときに、イプシロンでの使用は精度エラーを防ぐためにここにあります。

したがって、これからは標準の if/else ステートメントで使用できます。

if( IS_IPHONE_5 )
{}
else
{}

編集 - より良い検出

一部の人々が述べているように、これはワイドスクリーンのみを検出し、実際の iPhone 5 は検出しません。

iPod touch の次期バージョンにもこのような画面が搭載される可能性があるため、別のマクロ セットを使用する可能性があります。

元のマクロの名前を変更しましょうIS_WIDESCREEN:

#define IS_WIDESCREEN ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

そして、モデル検出マクロを追加しましょう:

#define IS_IPHONE ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPhone" ] )
#define IS_IPOD   ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPod touch" ] )

このようにして、iPhone モデルとワイドスクリーンがあることを確認IS_IPHONE_5、マクロを再定義できます。

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

また、@LearnCocos2D で述べられているように、アプリケーションが iPhone 5 画面用に最適化されていない場合 (Default-568h@2x.png 画像がない場合)、このマクロは機能しないことに注意してください。ケース。

最適化されていないアプリで iPhone 5 を検出する理由がわからないため、これが問題になるとは思いません。

重要 - iOS 8 のサポート

iOS 8 では、クラスのboundsプロパティがデバイスの向きUIScreenを反映するようになりました。 したがって、明らかに、前のコードはそのままでは機能しません。

これを修正するには、向きによって変化せず、縦向きモードに基づいているため、 のnativeBounds代わりに新しいプロパティを使用するだけです。 の寸法はピクセル単位で測定されるため、iPhone 5 の場合、高さは 568 ではなく1136になります。bounds
nativeBounds

iOS 7 以下もターゲットにしている場合は、nativeBoundsiOS 8 より前に呼び出すとアプリがクラッシュするため、必ず機能検出を使用してください。

if( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] )
{
    /* Detect using nativeBounds - iOS 8 and greater */
}
else
{
    /* Detect using bounds - iOS 7 and lower */
}

以前のマクロを次の方法で適応させることができます。

#define IS_WIDESCREEN_IOS7 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
#define IS_WIDESCREEN_IOS8 ( fabs( ( double )[ [ UIScreen mainScreen ] nativeBounds ].size.height - ( double )1136 ) < DBL_EPSILON )
#define IS_WIDESCREEN      ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_WIDESCREEN_IOS8 : IS_WIDESCREEN_IOS7 )

もちろん、iPhone 6 または 6 Plus を検出する必要がある場合は、対応する画面サイズを使用してください。

于 2012-09-16T13:08:38.907 に答える
232

SDK と OS の任意の組み合わせに対してテストおよび設計されています。

迅速

iPadの種類を追加。iPad 2 および iPad mini は非 Retina iPad です。iPad Mini 2 以降、iPad 3、4、iPad Air、Air 2、Air 3、iPad Pro 9.7 の論理解像度は同じ 1024 です。iPad Pro の maxLength は 1366 です

import UIKit

public enum DisplayType {
    case unknown
    case iphone4
    case iphone5
    case iphone6
    case iphone6plus
    case iPadNonRetina
    case iPad
    case iPadProBig
    static let iphone7 = iphone6
    static let iphone7plus = iphone6plus
}

public final class Display {
    class var width:CGFloat { return UIScreen.main.bounds.size.width }
    class var height:CGFloat { return UIScreen.main.bounds.size.height }
    class var maxLength:CGFloat { return max(width, height) }
    class var minLength:CGFloat { return min(width, height) }
    class var zoomed:Bool { return UIScreen.main.nativeScale >= UIScreen.main.scale }
    class var retina:Bool { return UIScreen.main.scale >= 2.0 }
    class var phone:Bool { return UIDevice.current.userInterfaceIdiom == .phone }
    class var pad:Bool { return UIDevice.current.userInterfaceIdiom == .pad }
    class var carplay:Bool { return UIDevice.current.userInterfaceIdiom == .carPlay }
    class var tv:Bool { return UIDevice.current.userInterfaceIdiom == .tv }
    class var typeIsLike:DisplayType {
        if phone && maxLength < 568 {
            return .iphone4
        }
        else if phone && maxLength == 568 {
                return .iphone5
        }
        else if phone && maxLength == 667 {
            return .iphone6
        }
        else if phone && maxLength == 736 {
            return .iphone6plus
        }
        else if pad && !retina {
            return .iPadNonRetina
        }
        else if pad && retina && maxLength == 1024 {
            return .iPad
        }
        else if pad && maxLength == 1366 {
            return .iPadProBig
        }
        return .unknown
    }
}

実際に見て ください https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

注: たとえば、iPhone 6 がズーム モードの場合、UI は iPhone 5 のズームアップ バージョンです。これらの関数はデバイス タイプを決定するのではなく、表示モードを決定するため、この例では iPhone 5 が望ましい結果となります。

Objective-C

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0)

#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
#define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
#define IS_ZOOMED (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

#define IS_IPHONE_4_OR_LESS (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
#define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
#define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

使用法: http://pastie.org/9687735

注: たとえば、iPhone 6 がズーム モードの場合、UI は iPhone 5 のズームアップ バージョンです。これらの関数はデバイス タイプを決定するのではなく、表示モードを決定するため、この例では iPhone 5 が望ましい結果となります。

于 2012-10-31T11:01:17.983 に答える
69

本当に簡単な解決策

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}
于 2012-09-25T17:20:28.550 に答える
28

ここで、iPhone 6 および 6Plus の画面サイズを考慮する必要があります。ここに更新された回答があります

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    //its iPhone. Find out which one?

    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    else if(result.height == 568)
    {
        // iPhone 5
    }
    else if(result.height == 667)
    {
        // iPhone 6
    }
   else if(result.height == 736)
    {
        // iPhone 6 Plus
    }
}
else
{
     //its iPad
}

役立つ情報

iPhone 6 Plus   736x414 points  2208x1242 pixels    3x scale    1920x1080 physical pixels   401 physical ppi    5.5"
iPhone 6        667x375 points  1334x750 pixels     2x scale    1334x750 physical pixels    326 physical ppi    4.7"
iPhone 5        568x320 points  1136x640 pixels     2x scale    1136x640 physical pixels    326 physical ppi    4.0"
iPhone 4        480x320 points  960x640 pixels      2x scale    960x640 physical pixels     326 physical ppi    3.5"
iPhone 3GS      480x320 points  480x320 pixels      1x scale    480x320 physical pixels     163 physical ppi    3.5"
于 2014-09-24T13:07:12.643 に答える
15

私は自由にMacmadeのマクロをC関数に入れ、ワイドスクリーンの可用性を検出し、必ずしもiPhone 5を検出するわけではないので、適切な名前を付けました。

プロジェクトにDefault-568h@2x.pngが含まれていない場合、マクロはiPhone5での実行も検出しません。新しいデフォルトの画像がない場合、iPhone 5は通常の480x320の画面サイズ(ポイント単位)を報告します。したがって、チェックはワイドスクリーンの可用性だけでなく、ワイドスクリーンモードが有効になっていることも確認します。

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}
于 2012-09-21T14:00:29.060 に答える
6

これは私の cocos2d プロジェクトのマクロです。他のアプリでも同じはずです。

#define WIDTH_IPAD 1024
#define WIDTH_IPHONE_5 568
#define WIDTH_IPHONE_4 480
#define HEIGHT_IPAD 768
#define HEIGHT_IPHONE 320

#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)

//width is height!
#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_5 )
#define IS_IPHONE_4 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_4 )

#define cp_ph4(__X__, __Y__) ccp(cx_ph4(__X__), cy_ph4(__Y__))
#define cx_ph4(__X__) (IS_IPAD ? (__X__ * WIDTH_IPAD / WIDTH_IPHONE_4) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPHONE_4) : (__X__)))
#define cy_ph4(__Y__) (IS_IPAD ? (__Y__ * HEIGHT_IPAD / HEIGHT_IPHONE) : (__Y__))

#define cp_pad(__X__, __Y__) ccp(cx_pad(__X__), cy_pad(__Y__))
#define cx_pad(__X__) (IS_IPAD ? (__X__) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPAD) : (__X__ * WIDTH_IPHONE_4 / WIDTH_IPAD)))
#define cy_pad(__Y__) (IS_IPAD ? (__Y__) : (__Y__ * HEIGHT_IPHONE / HEIGHT_IPAD))
于 2012-09-29T04:32:27.830 に答える
5
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}
于 2013-09-12T12:03:22.493 に答える
3

Swift では、次のような拡張機能を作成するのが好きな iOS 8+ プロジェクトUIScreen:

extension UIScreen {

    var isPhone4: Bool {
        return self.nativeBounds.size.height == 960;
    }

    var isPhone5: Bool {
        return self.nativeBounds.size.height == 1136;
    }

    var isPhone6: Bool {
        return self.nativeBounds.size.height == 1334;
    }

    var isPhone6Plus: Bool {
        return self.nativeBounds.size.height == 2208;
    }

}

(注:nativeBoundsピクセル単位です)。

そして、コードは次のようになります。

if UIScreen.mainScreen().isPhone4 {
    // do smth on the smallest screen
}

したがって、コードは、これがデバイス モデルではなく、メイン画面のチェックであることを明確にしています。

于 2016-05-22T15:37:56.067 に答える
2

Samrat Mazumdarの回答から借りて、デバイスの画面サイズを推定する簡単な方法を次に示します。最新のデバイスで動作しますが、将来のデバイスでは失敗する可能性があります(推測のすべての方法がそうであるように)。また、デバイスがミラーリングされている場合も混乱します(ミラーリングされた画面サイズではなく、デバイスの画面サイズを返します)

#define SCREEN_SIZE_IPHONE_CLASSIC 3.5
#define SCREEN_SIZE_IPHONE_TALL 4.0
#define SCREEN_SIZE_IPAD_CLASSIC 9.7

+ (CGFloat)screenPhysicalSize
{
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        if (result.height < 500)
            return SCREEN_SIZE_IPHONE_CLASSIC;  // iPhone 4S / 4th Gen iPod Touch or earlier
        else
            return SCREEN_SIZE_IPHONE_TALL;  // iPhone 5
    }
    else
    {
        return SCREEN_SIZE_IPAD_CLASSIC; // iPad
    }
} 
于 2012-10-10T23:25:50.010 に答える
2
+(BOOL)isDeviceiPhone5
{
    BOOL iPhone5 = FALSE;

    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    if (screenBounds.size.height == 568)
    {
        // code for 4-inch screen
        iPhone5 = TRUE;
    }
    else
    {
        iPhone5 = FALSE;
        // code for 3.5-inch screen
    }
    return iPhone5;

}
于 2014-05-19T14:41:52.237 に答える
2

これは何百回も回答されていますが、このソリューションは私にとって最もうまく機能し、新しいデバイスが導入され、サイズが定義されていないときに問題に対処するのに役立ちました.

Swift 5 ヘルパー:

extension UIScreen {
    func phoneSizeInInches() -> CGFloat {
        switch (self.nativeBounds.size.height) {
        case 960, 480:
            return 3.5  //iPhone 4
        case 1136:
            return 4    //iPhone 5
        case 1334:
            return 4.7  //iPhone 6
        case 2208:
            return 5.5  //iPhone 6 Plus
        case 2436:
            return 5.8  //iPhone X
        case 1792:
            return 6.1  //iPhone XR
        case 2688:
            return 6.5  //iPhone XS Max
        default:
            let scale = self.scale
            let ppi = scale * 163
            let width = self.bounds.size.width * scale
            let height = self.bounds.size.height * scale
            let horizontal = width / ppi, vertical = height / ppi
            let diagonal = sqrt(pow(horizontal, 2) + pow(vertical, 2))
            return diagonal
        }
    }
}

これは、「5.5 インチ」や「4.7 インチ」などのデバイスのインチ サイズを覚えるのは簡単ですが、正確なピクセル サイズを覚えるのは難しいためです。

if UIScreen.main.phoneSizeInInches() == 4 {
  //do something with only 4 inch iPhones
}

これにより、次のようなことを行う機会も得られます。

if UIScreen.main.phoneSizeInInches() < 5.5 {
  //do something on all iPhones smaller than the plus
}

デフォルト:画面サイズとスケールを使用して対角インチを計算しようとします。これは、新しいデバイス サイズが表示された場合に備えて、最後の例のようなコードを決定するために最善を尽くします。

于 2016-11-03T03:06:39.333 に答える
2

このマクロがデバイスとシミュレータで動作するのであれば良いと思います。以下に解決策を示します。

#define IS_WIDESCREEN (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON)
#define IS_IPHONE (([[[UIDevice currentDevice] model] isEqualToString:@"iPhone"]) || ([[[UIDevice currentDevice] model] isEqualToString: @"iPhone Simulator"]))
#define IS_IPOD   ([[[UIDevice currentDevice]model] isEqualToString:@"iPod touch"])
#define IS_IPHONE_5 ((IS_IPHONE || IS_IPOD) && IS_WIDESCREEN)
于 2013-02-08T10:38:10.130 に答える
1

サイズに依存することは、非常に多くのレベルで間違っています。システムに聞いてみませんか?

- (NSString *) getDeviceModel
{
    struct utsname systemInfo;
    uname(&systemInfo);
    return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}

ハードウェアの種類を検出する最良の方法、iPhone4 または iPhone5? から取得 、edzio27回答。

于 2013-02-28T23:03:46.500 に答える
1
CGFloat height = [UIScreen mainScreen].bounds.size.height;

NSLog(@"screen soze is %f",height);

  if (height>550) {

          // 4" screen-do some thing
     }

  else if (height<500) {

        // 3.5 " screen- do some thing

     }
于 2012-12-11T05:39:06.253 に答える
1

このようにして、デバイス ファミリを検出できます。

    #import <sys/utsname.h>
    NSString* deviceName()
    {
        struct utsname systemInformation;
        uname(&systemInformation);
        NSString *result = [NSString stringWithCString:systemInformation.machine
                                              encoding:NSUTF8StringEncoding];
        return result;
    }

    #define isIPhone5  [deviceName() rangeOfString:@"iPhone5,"].location != NSNotFound
    #define isIPhone5S [deviceName() rangeOfString:@"iPhone6,"].location != NSNotFound
于 2014-04-10T07:17:54.827 に答える
1
  1. 「新しいSwiftファイル」を追加->AppDelegateEx.swift

  2. に拡張子を追加するAppDelegate

    import UIKit
    extension AppDelegate {
         class func isIPhone5 () -> Bool{
             return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 568.0
        }
        class func isIPhone6 () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 667.0
        }
        class func isIPhone6Plus () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 736.0
        }  
    }
    
  3. 利用方法:

        if AppDelegate.isIPhone5() {
            collectionViewTopConstraint.constant = 2
        }else if AppDelegate.isIPhone6() {
            collectionViewTopConstraint.constant = 20
        }
    
于 2015-10-27T02:13:47.257 に答える
0

これは、向きに依存しない、デバイスの正しいテストです。

- (BOOL)isIPhone5
{
    CGSize size = [[UIScreen mainScreen] bounds].size;
    if (MIN(size.width,size.height) == 320 && MAX(size.width,size.height == 568)) {
        return YES;
    }
    return NO;
}
于 2016-04-13T12:58:25.920 に答える
0

次のコードを使用します。

CGFloat screenScale = [[UIScreen mainScreen] scale];

CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale); 

if (screenSize.height==1136.000000)
{ 
    // Here iPhone 5 View

    // Eg: Nextview~iPhone5.Xib
} else {
   // Previous Phones 

   // Eg : Nextview.xib
}
于 2012-10-10T07:18:50.153 に答える
-2

すべてのバージョンの iPhone および iPad デバイスを検出するために使用されます。

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0) 
于 2014-09-24T14:58:18.033 に答える