iOS 매크로로 iPhone X, iPhone 6 plus, iPhone 6, iPhone 5, iPhone 4를 감지하는 방법은 무엇입니까?


111

매크로로 장치 모델을 감지하는 방법은 무엇입니까? 나는 이런 것을 사용했지만 시뮬레이터의 결과는 항상 IS_IPHONE_5

#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_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)  

오래된 프로젝트에만 존재하는 문제입니다. 새로운 프로젝트 (Xcode 6에서 생성)에서는 모든 것이 괜찮습니다.
phuongho

3
시작 화면을 생성하고 모든 기본 발사 이미지를 삭제 : 고정
phuongho

1
실제 iPhone6 ​​기기에서는 #define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] scale] == 3.0f)를 사용해야합니다. nativeScale이 아닙니다.
Non Umemoto 2014 년

[[UIScreen mainScreen] nativeScale] == 3.0f (또는 배율)로 iPhone 6 Plus를 감지하는 것이 잘못되었습니다. 6+에서 실행되는 확장 된 iOS 앱을 사용하는 경우 잘못된 내용을보고합니다. nativeScale은 결코 3.0이 될 수 없습니다 .6 Plus에서는 2.60869입니다 (물리적 화면이 실제 3x가 아니기 때문에) 실행 환경을 감지하려면 스케일을 사용하는 것이 좋지만 기기 자체를 감지하려면 다른 기기를 사용해야합니다. 같은 방법 : stackoverflow.com/questions/11197509/…
Shazron

프로젝트에 시작 화면 XIB를 추가 @Milanpatel
phuongho

답변:


196

빠른

import UIKit

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

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 phone && maxLength == 812 {
            return .iphoneX
        }
        return .unknown
    }
}

실제 모습보기 https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

참고 : 예를 들어 iPhone 6이 확대 모드 인 경우 UI는 iPhone 5의 확대 된 버전입니다. 이러한 기능은 장치 유형을 결정하는 것이 아니라 디스플레이 모드이므로이 예에서는 iPhone 5가 원하는 결과입니다.

목표 -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)
#define IS_IPHONE_X (IS_IPHONE && SCREEN_MAX_LENGTH == 812.0)

사용법 : http://pastie.org/9687735

참고 : 예를 들어 iPhone 6이 확대 모드 인 경우 UI는 iPhone 5의 확대 된 버전입니다. 이러한 기능은 장치 유형을 결정하는 것이 아니라 디스플레이 모드이므로이 예에서는 iPhone 5가 원하는 결과입니다.


3
IS_IPHONE_6 및 IS_IPHONE_6P는 시뮬레이터에서 작동하지 않습니다. 보고 된 최대 길이는 568입니다. 내가 누락 된 것이 있습니까?
Christopher

6
확대 모드입니까? iPhone 6 용 시작 화면이 있습니까?
hfossli 2014

5
이것은 나에게 전반적으로 잘못된 방향으로 보입니다. 이것은 멀지 않은 미래에 분명히 깨질 것입니다.
Jonny 2015 년

1
@Jonny : 대안?
테스트

1
@Jonny : 일반적으로 당신 말이 맞지만, 모델이나 적어도 해상도를 알고 있다면 이것을 활용할 수있는 애플리케이션을 알고 있습니다. 기기 유형에 따라 하루의 너비를 조정하는 캘린더 애플리케이션의 주간보기입니다. 이를 통해 정확한 일수를 동시에 표시 할 수 있습니다. 이 솔루션이 없으면 다른 날의 일부만 볼 수 있습니다.
테스트

62

Swift의 경우 :

struct ScreenSize
{
    static let SCREEN_WIDTH = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
}

struct DeviceType
{
    static let IS_IPHONE_4_OR_LESS =  UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_5 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_6 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_6P = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
}

7
UIUserInterfaceIdiom 열거 형 필요 없음, UIKit 가져 오기
Vilém Kurz

수백만 명의 사용자에게 앱을 배포 할 계획이라면 권장하지 않습니다. 사용자가 장치의 디스플레이 설정에서 "줌"(일반 "표준"대신)을 활성화 한 경우이 결과를 확인하십시오. 이 경우이 코드는 중단됩니다. 개인적으로 mcm의 답변을 사용하는 것이 좋습니다.
디팍 딴

아주 좋아. 정적 let 속성은 이것을 매우 효율적으로 만듭니다!
hfossli

iPhone X는 어떻습니까?
vikzilla

15
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) // iPhone and       iPod touch style UI

#define IS_IPHONE_5_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0f)
#define IS_IPHONE_6_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0f)
#define IS_IPHONE_6P_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height < 568.0f)

#define IS_IPHONE_5_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 568.0f)
#define IS_IPHONE_6_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 667.0f)
#define IS_IPHONE_6P_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) < 568.0f)

#define IS_IPHONE_5 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_5_IOS8 : IS_IPHONE_5_IOS7 )
#define IS_IPHONE_6 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6_IOS8 : IS_IPHONE_6_IOS7 )
#define IS_IPHONE_6P ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6P_IOS8 : IS_IPHONE_6P_IOS7 )
#define IS_IPHONE_4_AND_OLDER ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_4_AND_OLDER_IOS8 : IS_IPHONE_4_AND_OLDER_IOS7 )

IS_IPHONE_6_IOS7그리고 IS_IPHONE_6P_IOS7아이폰 6 (+)가 단지 위의 아이폰 OS 8에있을 수 있습니다, 필요하지 않습니다.
Robert

아이폰 6과 아이폰 6 플러스는 iOS 8 이상 만 설치할 수 있다는 뜻입니까? 내가 당신의 요점을 알고 있습니까?
Waqas Haider Sheikh

예 - 아이폰 6 (+)는 아이폰 OS 8과 함께 제공하며 다운 그레이드 할 수 없습니다
로버트

.size.height == 568.0f는 iPhone 5가 가로
모드

나는 풍경에서도 그것을 테스트하고 정답을주고 자세히 알려주십시오.
Waqas Haider Sheikh

14
public extension UIDevice {

    var iPhone: Bool {
        return UIDevice().userInterfaceIdiom == .Phone
    }

    enum ScreenType: String {
        case iPhone4
        case iPhone5
        case iPhone6
        case iPhone6Plus
        case Unknown
    }
    var screenType: ScreenType {
        guard iPhone else { return .Unknown}
        switch UIScreen.mainScreen().nativeBounds.height {
        case 960:
            return .iPhone4
        case 1136:
            return .iPhone5
        case 1334:
            return .iPhone6
        case 1920: //fallthrough
            return .iPhone6Plus
        case 2208:
            return .iPhone6Plus
        default:
            return .Unknown
        }
    }

}

1
iPhone 6 Plus의 기본 높이는 1920이 아닌 2208입니다. 답변을 수정했습니다.
salocinx

1
+1. nativeBounds보다 사용하는 것이 좋습니다 bounds. Display Zoom이 켜져있는 iPhone 6은 앱 내에서 Display Zoom이 아무런 영향을 미치지 않더라도 bounds.height에 대해 568을보고하지만 nativeBounds.height에 대해 1334를보고합니다. ( support.apple.com/en-us/HT203073 )
Christopher Pickslay

@salocinx iPhone 6/7 plus 용 Xcode에서 1920.0이 반환되었습니다.
Siriss

우리는 여기에 두 가지 경우 모두를 사용한다 : - 경우 1920 위해 fallthrough 경우 2208 : 리턴 .iPhone6Plus을
kalpesh jetani

1
iPhone plus는 물리적 장치에서 1920이고 시뮬레이터에서 2208입니다. 장치의 3 배 밀도에서 축소 되었기 때문입니다.
Alessandro Martin

10

실제 시스템 정보를 가져 오는 클래스를 사용합니다. 모든 장치 유형이 최신인지 확인하기 만하면됩니다.

#import "Macros.h"

@implementation Macros

+ (BOOL)IS_IPHONE_6_PLUS {
    return [[self deviceType] isEqualToString:@"iPhone 6 Plus"] ||  [[self deviceType] isEqualToString:@"iPhone 6S Plus"];
}

+ (BOOL)IS_IPHONE_6 {
    return [[self deviceType] isEqualToString:@"iPhone 6"] || [[self deviceType] isEqualToString:@"iPhone 6S"];
}

+ (BOOL)IS_SIMULATOR {
    return [[self deviceType] isEqualToString:@"32-bit Simulator"]
           || [[self deviceType] isEqualToString:@"64-bit Simulator"];
}

+ (BOOL)IS_IPHONE_5 {
    NSString *device = [self deviceType];
    BOOL result = [device isEqualToString:@"iPhone 5(GSM)"] || [device isEqualToString:@"iPhone 5(GSM+CDMA)"]
                  || [device isEqualToString:@"iPhone 5C(GSM)"] || [device isEqualToString:@"iPhone 5C(GSM+CDMA)"]
                  || [device isEqualToString:@"iPhone 5S(GSM)"] || [device isEqualToString:@"iPhone 5S(GSM+CDMA)"];
    return result;
}

/*
 @"i386"      on 32-bit Simulator
 @"x86_64"    on 64-bit Simulator
 @"iPod1,1"   on iPod Touch
 @"iPod2,1"   on iPod Touch Second Generation
 @"iPod3,1"   on iPod Touch Third Generation
 @"iPod4,1"   on iPod Touch Fourth Generation
 @"iPod5,1"   on iPod Touch Fifth Generation
 @"iPhone1,1" on iPhone
 @"iPhone1,2" on iPhone 3G
 @"iPhone2,1" on iPhone 3GS
 @"iPad1,1"   on iPad
 @"iPad2,1"   on iPad 2
 @"iPad3,1"   on 3rd Generation iPad
 @"iPad3,2":  on iPad 3(GSM+CDMA)
 @"iPad3,3":  on iPad 3(GSM)
 @"iPad3,4":  on iPad 4(WiFi)
 @"iPad3,5":  on iPad 4(GSM)
 @"iPad3,6":  on iPad 4(GSM+CDMA)
 @"iPhone3,1" on iPhone 4
 @"iPhone4,1" on iPhone 4S
 @"iPad3,4"   on 4th Generation iPad
 @"iPad2,5"   on iPad Mini
 @"iPhone5,1" on iPhone 5(GSM)
 @"iPhone5,2" on iPhone 5(GSM+CDMA)
 @"iPhone5,3  on iPhone 5c(GSM)
 @"iPhone5,4" on iPhone 5c(GSM+CDMA)
 @"iPhone6,1" on iPhone 5s(GSM)
 @"iPhone6,2" on iPhone 5s(GSM+CDMA)
 @"iPhone7,1" on iPhone 6 Plus
 @"iPhone7,2" on iPhone 6
 @"iPhone8,1" on iPhone 6  
 @"iPhone8,2" on iPhone 6 Plus ...Yes Apple switched the order...
 */

+ (NSString *)deviceType {
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *result = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
        // https://www.theiphonewiki.com/wiki/Models
        NSDictionary *matches = @{
                          @"i386" : @"32-bit Simulator",
                          @"x86_64" : @"64-bit Simulator",

                          @"iPod1,1" : @"iPod Touch",
                          @"iPod2,1" : @"iPod Touch Second Generation",
                          @"iPod3,1" : @"iPod Touch Third Generation",
                          @"iPod4,1" : @"iPod Touch Fourth Generation",
                          @"iPod5,1" : @"iPod Touch Fifth Generation",

                          @"iPad1,1" : @"iPad",
                          @"iPad2,1" : @"iPad 2",
                          @"iPad2,2" : @"iPad 2",
                          @"iPad2,3" : @"iPad 2",
                          @"iPad2,4" : @"iPad 2",
                          @"iPad2,5" : @"iPad Mini",
                          @"iPad2,6" : @"iPad Mini",
                          @"iPad2,7" : @"iPad Mini",
                          @"iPad3,1" : @"iPad 3",
                          @"iPad3,2" : @"iPad 3(GSM+CDMA)",
                          @"iPad3,3" : @"iPad 3(GSM)",
                          @"iPad3,4" : @"iPad 4(WiFi)",
                          @"iPad3,5" : @"iPad 4(GSM)",
                          @"iPad3,6" : @"iPad 4(GSM+CDMA)",
                          @"iPad4,1" : @"iPad Air",
                          @"iPad4,2" : @"iPad Air",
                          @"iPad4,3" : @"iPad Air",
                          @"iPad4,4" : @"iPad Mini 2",
                          @"iPad4,5" : @"iPad Mini 2",
                          @"iPad4,6" : @"iPad Mini 2",
                          @"iPad4,7" : @"iPad Mini 3",
                          @"iPad4,8" : @"iPad Mini 3",
                          @"iPad4,9" : @"iPad Mini 3",
                          @"iPad5,1" : @"iPad Mini 4",
                          @"iPad5,2" : @"iPad Mini 4",
                          @"iPad5,3" : @"iPad Air 2",
                          @"iPad5,4" : @"iPad Air 2",
                          @"iPad6,3" : @"iPad Pro (9.7in)",
                          @"iPad6,4" : @"iPad Pro (9.7in)",
                          @"iPad6,7" : @"iPad Pro (12.9in)",
                          @"iPad6,8" : @"iPad Pro (12.9in)",

                          @"iPhone1,1" : @"iPhone",
                          @"iPhone1,2" : @"iPhone 3G",
                          @"iPhone2,1" : @"iPhone 3GS",
                          @"iPhone3,1" : @"iPhone 4",
                          @"iPhone3,3" : @"iPhone 4",
                          @"iPhone4,1" : @"iPhone 4S",
                          @"iPhone5,1" : @"iPhone 5(GSM)",
                          @"iPhone5,2" : @"iPhone 5(GSM+CDMA)",
                          @"iPhone5,3" : @"iPhone 5C(GSM)",
                          @"iPhone5,4" : @"iPhone 5C(GSM+CDMA)",
                          @"iPhone6,1" : @"iPhone 5S(GSM)",
                          @"iPhone6,2" : @"iPhone 5S(GSM+CDMA)",
                          @"iPhone7,1" : @"iPhone 6 Plus",
                          @"iPhone7,2" : @"iPhone 6",
                          @"iPhone8,1" : @"iPhone 6S",
                          @"iPhone8,2" : @"iPhone 6S Plus",
                          @"iPhone8,4" : @"iPhone SE",
                          @"iPhone9,1" : @"iPhone 7",
                          @"iPhone9,3" : @"iPhone 7",
                          @"iPhone9,2" : @"iPhone 7 Plus",
                          @"iPhone9,4" : @"iPhone 7 Plus",
                          };

    if (matches[result]) {
        return matches[result];
    } else {
        return result;
    }
}

@end

3
#import <sys / utsname.h>
Deepak Thakur

7

실행 화면을 설정하면 버그가 사라진 것을 확인할 수 있습니다.

실행 이미지를 유지하고 MainStoryboard를 Launch Screen에 추가하면 시뮬레이터가 장치를 올바르게 인식했습니다.


시작 화면이없는 오래된 프로젝트의 경우 버그가 있습니다. Launch Screen이 문제를 해결했습니다.
BHuelse

6

코드를 장치 유형과 바인딩하지 않는 것이 좋습니다. 이것은 융통성이없는 복잡한 것으로 이어질 것입니다. Apple은 기기가 아닌 크기에 대해 생각하기를 바랍니다. 이미지 또는 글꼴 크기와 같이 iPhone 5보다 큰 장치에 대한 특수 크기가 필요한 경우 iPhone 5 화면 간의 관계에 따라 기본 크기를 일정 비율로 늘리는 승수를 사용하여 정규화 클래스를 만드는 것이 좋습니다. 너비 및 현재 장치 크기.

let BaseWidth : CGFloat = 320

class Normalizer: NSObject {
    //scale value proportional to the screen width
    class func normalize(value:CGFloat,multiplier : CGFloat = 1,maxDelta:CGFloat = 1024) -> CGFloat{
        let screenWidth = UIScreen.mainScreen().bounds.size.width
        let percent = (screenWidth - BaseWidth)/screenWidth
        let normalizedValue = value * (1 + percent) * multiplier
        return min(normalizedValue, value + maxDelta)//capped by a max value if needed
    } 
}

따라서 코드에서 다음과 같이 할 것입니다.

value = Normalizer.normalize(30)

왜 구조체를 사용하지 static normalize않습니까?
Kalzem 2014

너무 작업을해야하지만 구조체는 데이터 처리를 위해 주로 생각
mukaissi

6

Swift 3+ 구문을 사용한 UIDeivce 확장 .

public extension UIDevice {

    var iPhone: Bool {
        return UIDevice().userInterfaceIdiom == .phone
    }

    enum ScreenType: String {
        case iPhone4
        case iPhone5
        case iPhone6
        case iPhone6Plus
        case iPhoneX
        case Unknown
    }
    var screenType: ScreenType {
        guard iPhone else { return .Unknown}
        switch UIScreen.main.nativeBounds.height {
        case 960:
            return .iPhone4
        case 1136:
            return .iPhone5
        case 1334:
            return .iPhone6
        case 2208, 1920:
            return .iPhone6Plus
        case 2436:
            return .iPhoneX
        default:
            return .Unknown
        }
    }

}

샘플 사용법 :

switch UIDevice().screenType {
        case .iPhone4, .iPhone5:
            // Code for iPhone 4 & iPhone 5
            break
        case .iPhone6:
            // Code for iPhone 6 & iPhone 7
            break
        case .iPhone6Plus:
            // Code for iPhone 6 Plus & iPhone 7 Plus
            break
        case .iPhoneX:
            // Code for iPhone X
            break
        default:
            break
        }

원래 답변 : https://stackoverflow.com/a/36479017/3659227


5

Xcode 11 / Swift 5.1 업데이트 :

enum UIUserInterfaceIdiom : Int
{
    case Unspecified
    case Phone
    case Pad
}

struct ScreenSize
{
    static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
}

struct DeviceType
{
    static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_5          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_6_8        = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_6_8P       = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    static let IS_IPHONE_X          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 812.0
    static let IS_IPHONE_11_PRO     = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 812.0
    static let IS_IPHONE_XR_SMAX    = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 896.0
    static let IS_IPHONE_XS_MAX     = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 896.0
    static let IS_IPHONE_11         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 896.0
    static let IS_IPHONE_11_PRO_MAX = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 896.0
    static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0
    static let IS_IPAD_PRO10        = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1112.0
    static let IS_IPAD_PRO12        = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0
    static let IS_IPAD_ALL          = UIDevice.current.userInterfaceIdiom == .pad

    static let IS_IPHONE_NOTCH_DEVICE = (UIDevice.current.userInterfaceIdiom == .phone) && (ScreenSize.SCREEN_MAX_LENGTH == 896.0 || ScreenSize.SCREEN_MAX_LENGTH == 812.0)
}

struct Version{
    static let SYS_VERSION_FLOAT = (UIDevice.current.systemVersion as NSString).floatValue
    static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0 && Version.SYS_VERSION_FLOAT < 10.0)
    static let iOS10 = (Version.SYS_VERSION_FLOAT >= 10.0 && Version.SYS_VERSION_FLOAT < 11.0)
    static let iOS11 = (Version.SYS_VERSION_FLOAT >= 11.0 && Version.SYS_VERSION_FLOAT < 12.0)
    static let iOS12 = (Version.SYS_VERSION_FLOAT >= 12.0 && Version.SYS_VERSION_FLOAT < 13.0)
    static let iOS13 = (Version.SYS_VERSION_FLOAT >= 13.0)
}

struct VersionAndNewer {
    static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0)
    static let iOS10 = (Version.SYS_VERSION_FLOAT >= 10.0)
    static let iOS11 = (Version.SYS_VERSION_FLOAT >= 11.0)
    static let iOS12 = (Version.SYS_VERSION_FLOAT >= 12.0)
    static let iOS13 = (Version.SYS_VERSION_FLOAT >= 13.0)
}

안녕하세요 저는 Xcode10 / Swift 4.2 및 IPhone XS / XSMAX / XR의 새로운 크기로 업데이트했습니다.

Notch-IPhone을 감지합니다.

이것이 누군가를 돕기를 바랍니다.

enum UIUserInterfaceIdiom : Int
{
    case Unspecified
    case Phone
    case Pad

}

struct ScreenSize
{
    static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
}

struct DeviceType
{
    static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_5          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_6_8        = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_6_8P       = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    static let IS_IPHONE_X          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 812.0
    static let IS_IPHONE_XR_SMAX    = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 896.0
    static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0
    static let IS_IPAD_PRO10        = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1112.0
    static let IS_IPAD_PRO12        = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0

    static let IS_IPHONE_NOTCH_DEVICE = (UIDevice.current.userInterfaceIdiom == .phone) && (ScreenSize.SCREEN_MAX_LENGTH == 896.0 || ScreenSize.SCREEN_MAX_LENGTH == 812.0)
}

struct Version{
    static let SYS_VERSION_FLOAT = (UIDevice.current.systemVersion as NSString).floatValue
    static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0 && Version.SYS_VERSION_FLOAT < 10.0)
    static let iOS10 = (Version.SYS_VERSION_FLOAT >= 10.0 && Version.SYS_VERSION_FLOAT < 11.0)
    static let iOS11 = (Version.SYS_VERSION_FLOAT >= 11.0 && Version.SYS_VERSION_FLOAT < 12.0)
    static let iOS12 = (Version.SYS_VERSION_FLOAT >= 12.0)
}

struct VersionAndNewer {
    static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0)
    static let iOS10 = (Version.SYS_VERSION_FLOAT >= 10.0)
    static let iOS11 = (Version.SYS_VERSION_FLOAT >= 11.0)
    static let iOS12 = (Version.SYS_VERSION_FLOAT >= 12.0)

}


1
//Device Type enum
enum DeviceType: Int {

//Apple UnknownDevices
case UnknownDevice = 0

//Simulator
case Simulator

//Apple Air pods
case AppleAirPods

//Apple TV
case AppleTV2G
case AppleTV3G
case AppleTV4G
case AppleTV4K

//Apple Watch
case AppleWatch
case AppleWatchSeries1
case AppleWatchSeries2
case AppleWatchSeries3

//Apple Home Pods
case AppleHomePods

//Apple iPad
case AppleIpad
case AppleIpad2
case AppleIpad3
case AppleIpad4
case AppleIpadAir
case AppleIpadAir2
case AppleIpadPro_12_9
case AppleIpadPro_9_7
case AppleIpad5
case AppleIpadPro_12_9_Gen_2
case AppleIpadPro_10_5
case AppleIpadMini
case AppleIpadMini2
case AppleIpadMini3
case AppleIpadMini4

//Apple iPhone
case AppleIphone
case AppleIphone3G
case AppleIphone3GS
case AppleIphone4
case AppleIphone4S
case AppleIphone5
case AppleIphone5C
case AppleIphone5S
case AppleIphone6
case AppleIphone6P
case AppleIphone6S
case AppleIphone6SP
case AppleIphoneSE
case AppleIphone7
case AppleIphone7P
case AppleIphone8
case AppleIphone8P
case AppleIphoneX

//Apple iPod touch
case AppleIpodTouch
case AppleIpodTouch2G
case AppleIpodTouch3G
case AppleIpodTouch4G
case AppleIpodTouch5G
case AppleIpodTouch6G
}

// Method for device type
func getDeviceType() -> DeviceType{
    var systemInfo = utsname()
    uname(&systemInfo)
    let machineMirror = Mirror(reflecting: systemInfo.machine)
    let identifier = machineMirror.children.reduce("") { identifier, element in
        guard let value = element.value as? Int8, value != 0 else { return identifier }
        return identifier + String(UnicodeScalar(UInt8(value)))
    }

    switch identifier {

    //Simulator
    case "i386","x86_64": return .Simulator

    //Apple Air Pods
    case "AirPods1,1": return .AppleAirPods

    //Apple TV
    case "AppleTV2,1": return .AppleTV2G
    case "AppleTV3,1", "AppleTV3,2": return .AppleTV3G
    case "AppleTV5,3": return .AppleTV4G
    case "AppleTV6,2": return .AppleTV4K

    //Apple Watch
    case "Watch1,1", "Watch1,2": return .AppleWatch
    case "Watch2,6", "Watch2,7": return .AppleWatchSeries1
    case "Watch2,3", "Watch2,4": return .AppleWatchSeries2
    case "Watch3,1", "Watch3,2", "Watch3,3", "Watch3,4": return .AppleWatchSeries3

    // Apple HomePods
    case "AudioAccessory1,1": return .AppleHomePods

    //Apple iPad
    case "iPad1,1": return .AppleIpad
    case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return .AppleIpad2
    case "iPad3,1", "iPad3,2", "iPad3,3": return .AppleIpad3
    case "iPad3,4", "iPad3,5", "iPad3,6": return .AppleIpad4
    case "iPad4,1", "iPad4,2", "iPad4,3": return .AppleIpadAir
    case "iPad5,3", "iPad5,4": return .AppleIpadAir2
    case "iPad6,7", "iPad6,8": return .AppleIpadPro_12_9
    case "iPad6,3", "iPad6,4": return .AppleIpadPro_9_7
    case "iPad6,11", "iPad6,12": return .AppleIpad5
    case "iPad7,1", "iPad7,2" : return .AppleIpadPro_12_9_Gen_2
    case "iPad7,3", "iPad7,4" : return .AppleIpadPro_10_5
    case "iPad2,5", "iPad2,6", "iPad2,7": return .AppleIpadMini
    case "iPad4,4", "iPad4,5", "iPad4,6": return .AppleIpadMini2
    case "iPad4,7", "iPad4,8", "iPad4,9": return .AppleIpadMini3
    case "iPad5,1", "iPad5,2": return .AppleIpadMini4

    //Apple iPhone
    case "iPhone1,1": return .AppleIphone
    case "iPhone1,2": return .AppleIphone3G
    case "iPhone2,1": return .AppleIphone3GS
    case "iPhone3,1", "iPhone3,2", "iPhone3,3": return .AppleIphone4
    case "iPhone4,1": return .AppleIphone4S
    case "iPhone5,1", "iPhone5,2": return .AppleIphone5
    case "iPhone5,3", "iPhone5,4": return .AppleIphone5C
    case "iPhone6,1", "iPhone6,2": return .AppleIphone5S
    case "iPhone7,2": return .AppleIphone6
    case "iPhone7,1": return .AppleIphone6P
    case "iPhone8,1": return .AppleIphone6S
    case "iPhone8,2": return .AppleIphone6SP
    case "iPhone8,4": return .AppleIphoneSE
    case "iPhone9,1", "iPhone9,3": return .AppleIphone7
    case "iPhone9,2", "iPhone9,4": return .AppleIphone7P
    case "iPhone10,1", "iPhone10,4": return .AppleIphone8
    case "iPhone10,2", "iPhone10,5": return .AppleIphone8P
    case "iPhone10,3", "iPhone10,6": return .AppleIphoneX

    //Apple iPod touch
    case "iPod1,1": return .AppleIpodTouch
    case "iPod2,1": return .AppleIpodTouch2G
    case "iPod3,1": return .AppleIpodTouch3G
    case "iPod4,1": return .AppleIpodTouch4G
    case "iPod5,1": return .AppleIpodTouch5G
    case "iPod7,1": return .AppleIpodTouch6G

    default:
        return .UnknownDevice
    }
}

0

플러스의 경우 줌도 확인해야합니다.

struct DeviceType
{
    static let IS_IPHONE = (UIDevice.current.userInterfaceIdiom == .phone)
    static let IS_IPHONE_4_OR_LESS =  UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_5 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_6_7 = (UIDevice.current.userInterfaceIdiom == .phone) && (ScreenSize.SCREEN_MAX_LENGTH == 667.0) && (UIScreen.main.nativeScale >= UIScreen.main.scale)
    private static let IS_STANDARD_IPHONE_6P_7P = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    private static let IS_ZOOMED_IPHONE_6P_7P = (UIDevice.current.userInterfaceIdiom == .phone) && (ScreenSize.SCREEN_MAX_LENGTH == 667.0) && (UIScreen.main.nativeScale < UIScreen.main.scale)
    static let IS_IPHONE_6P_7P = IS_STANDARD_IPHONE_6P_7P || IS_ZOOMED_IPHONE_6P_7P
}

0
import Foundation
import UIKit

public enum IADisplayType {
    // unknow device
    case        unspecified
    // iPhone
    case        unknowiPhone
    case        iPhone3GS
    case        iPhone4
    static let  iPhone4s            = iPhone5
    case        iPhone5
    static let  iPhone5s            = iPhone5
    static let  iPhoneSE            = iPhone5
    case        iPhone6
    case        iPhone6Plus
    static let  iPhone6s            = iPhone6
    static let  iPhone6sPlus        = iPhone6Plus
    static let  iPhone7             = iPhone6
    static let  iPhone7Plus         = iPhone6Plus
    static let  iPhone8             = iPhone6
    static let  iPhone8Plus         = iPhone6Plus
    case        iPhoneX
    // iPad
    case        unknowiPad
    case        iPad79
    static let  iPad97              = iPad79
    case        iPad105
    case        iPad129
    // Apple CarPlay
    case        carPlay
    // Apple TV
    case        tv
}

public final class IADisplayManager {

    // MARK: - public interface
    // singleton
    static var shared: IADisplayManager {
        get {
            return IADisplayManager()
        }
    }

    // get current device type
    public var currentType: IADisplayType {
        get {
            return calCurrentType()
        }
    }

    // device current Native Resolution
    public var nativeResolution: CGSize {
        get {
            return UIScreen.main.nativeBounds.size
        }
    }

    // device current Native Scale Factor
    public var nativeScaleFactor: CGFloat {
        get {
            return UIScreen.main.nativeScale
        }
    }

    // device current Interface Idiom
    public var interfaceIdiom: UIUserInterfaceIdiom {
        get {
            return UIDevice().userInterfaceIdiom
        }
    }

    fileprivate init() {}

    // MARK: - private interface
    fileprivate func calCurrentType() -> IADisplayType {
        typealias Type = IADisplayType

        // unknown device
        if interfaceIdiom == .unspecified { return Type.unspecified }
        // iPhone && iPod Touch
        else if interfaceIdiom == .phone {
            if nativeScaleFactor == 1.0 && nativeResolution == CGSize(width: 320, height: 480) { return Type.iPhone3GS }
            else if nativeScaleFactor == 2.0 && nativeResolution == CGSize(width: 640, height: 960) { return Type.iPhone4 }
            else if nativeScaleFactor == 2.0 && nativeResolution == CGSize(width: 640, height: 1136) { return Type.iPhone5 }
            else if nativeScaleFactor == 2.0 && nativeResolution == CGSize(width: 750, height: 1334) { return Type.iPhone6 }
            else if (nativeScaleFactor-2.608) < 0.001 && nativeResolution == CGSize(width: 1080, height: 1920) { return Type.iPhone6Plus }
            else if nativeScaleFactor == 3.0 && nativeResolution == CGSize(width: 1125, height: 2436) { return Type.iPhoneX }
            else { return Type.unknowiPhone }
        }
        // iPad
        else if interfaceIdiom == .pad {
            if nativeScaleFactor == 2.0 && nativeResolution == CGSize(width: 1536, height: 2048) { return Type.iPad79 }
            else if nativeScaleFactor == 2.0 && nativeResolution == CGSize(width: 2224, height: 1668) { return Type.iPad105 }
            else if nativeScaleFactor == 2.0 && nativeResolution == CGSize(width: 2048, height: 2732) { return Type.iPad129 }
            else { return Type.unknowiPad }
        }
        // Apple CarPlay
        else if interfaceIdiom == .carPlay { return Type.carPlay }
        // Apple TV
        else if interfaceIdiom == .tv { return Type.tv }
        // unknown device
        else { return Type.unspecified }
    }

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.