Обнаружение размеров экрана iPhone 6/6+ в точечных значениях


учитывая недавно анонсированный iPhone 6 размеры экрана:

iPhone 6: 1334h * 750w @2x (in points: 667h * 375w)
iPhone 6+: 1920 * 1080 @3x (in points: 640h * 360w)

мне было интересно, если есть код, который позволяет мне определить, какой размер экрана устройства пользователя, так что я мог бы настроить и размер UIImages и другие материалы соответственно с прибором потребителя.

до сих пор я использовал следующее:

- (NSString *) platform{
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *machine = malloc(size);
    sysctlbyname("hw.machine", machine, &size, NULL, 0);
    NSString *platform = [NSString stringWithUTF8String:machine];
    free(machine);
    return platform;
}

- (NSString *) platformString{
    NSString *platform = [self platform];
    if ([platform isEqualToString:@"iPhone1,1"])    return @"iPhone 1G";
    if ([platform isEqualToString:@"iPhone1,2"])    return @"iPhone 3G";
    if ([platform isEqualToString:@"iPhone2,1"])    return @"iPhone 3GS";
    if ([platform isEqualToString:@"iPhone3,1"])    return @"iPhone 4";
    if ([platform isEqualToString:@"iPhone3,3"])    return @"Verizon iPhone 4";
    if ([platform isEqualToString:@"iPhone4,1"])    return @"iPhone 4S";
    if ([platform isEqualToString:@"iPhone5,1"])    return @"iPhone 5 (GSM)";
    if ([platform isEqualToString:@"iPhone5,2"])    return @"iPhone 5 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPhone5,3"])    return @"iPhone 5c (GSM)";
    if ([platform isEqualToString:@"iPhone5,4"])    return @"iPhone 5c (GSM+CDMA)";
    if ([platform isEqualToString:@"iPhone6,1"])    return @"iPhone 5s (GSM)";
    if ([platform isEqualToString:@"iPhone6,2"])    return @"iPhone 5s (GSM+CDMA)";
    if ([platform isEqualToString:@"iPod1,1"])      return @"iPod Touch 1G";
    if ([platform isEqualToString:@"iPod2,1"])      return @"iPod Touch 2G";
    if ([platform isEqualToString:@"iPod3,1"])      return @"iPod Touch 3G";
    if ([platform isEqualToString:@"iPod4,1"])      return @"iPod Touch 4G";
    if ([platform isEqualToString:@"iPod5,1"])      return @"iPod Touch 5G";
    if ([platform isEqualToString:@"iPad1,1"])      return @"iPad";
    if ([platform isEqualToString:@"iPad2,1"])      return @"iPad 2 (WiFi)";
    if ([platform isEqualToString:@"iPad2,2"])      return @"iPad 2 (GSM)";
    if ([platform isEqualToString:@"iPad2,3"])      return @"iPad 2 (CDMA)";
    if ([platform isEqualToString:@"iPad2,4"])      return @"iPad 2 (WiFi)";
    if ([platform isEqualToString:@"iPad2,5"])      return @"iPad Mini (WiFi)";
    if ([platform isEqualToString:@"iPad2,6"])      return @"iPad Mini (GSM)";
    if ([platform isEqualToString:@"iPad2,7"])      return @"iPad Mini (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad3,1"])      return @"iPad 3 (WiFi)";
    if ([platform isEqualToString:@"iPad3,2"])      return @"iPad 3 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad3,3"])      return @"iPad 3 (GSM)";
    if ([platform isEqualToString:@"iPad3,4"])      return @"iPad 4 (WiFi)";
    if ([platform isEqualToString:@"iPad3,5"])      return @"iPad 4 (GSM)";
    if ([platform isEqualToString:@"iPad3,6"])      return @"iPad 4 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad4,1"])      return @"iPad Air (WiFi)";
    if ([platform isEqualToString:@"iPad4,2"])      return @"iPad Air (Cellular)";
    if ([platform isEqualToString:@"iPad4,4"])      return @"iPad mini 2G (WiFi)";
    if ([platform isEqualToString:@"iPad4,5"])      return @"iPad mini 2G (Cellular)";
    if ([platform isEqualToString:@"i386"])         return @"Simulator";
    if ([platform isEqualToString:@"x86_64"])       return @"Simulator";
    return platform;
}

как таковой, я должен предположить iPhone7,1 и iPhone7,2 являются iPhone 6 в то время как iPhone7,3 и iPhone7.4 плюсы? Если у кого-нибудь есть более конкретный способ сказать, что это было бы здорово, спасибо.!

16   58  

16 ответов:

первый экран будет экран устройства, обратите внимание, что запуск изображения для новых телефонов должны быть добавлены раньше, в противном случае приложение работает в режиме масштабирования для старых приложений : Вот код, который я использовал, чтобы проверить это. Примечание: это работает только с версией iOS 8 и выше:

UIScreen *mainScreen = [UIScreen mainScreen];
NSLog(@"Screen bounds: %@, Screen resolution: %@, scale: %f, nativeScale: %f",
          NSStringFromCGRect(mainScreen.bounds), mainScreen.coordinateSpace, mainScreen.scale, mainScreen.nativeScale);

код для обнаружения iPhone 6 Plus:

#define IS_PAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_PHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)

-(BOOL)iPhone6PlusDevice{
    if (!IS_PHONE) return NO;
    if ([UIScreen mainScreen].scale > 2.9) return YES;   // Scale is only 3 when not in scaled mode for iPhone 6 Plus
    return NO;
}

или

-(BOOL) iPhone6PlusUnZoomed{
    if ([self iPhone6PlusDevice]){
        if ([UIScreen mainScreen].bounds.size.height > 720.0) return YES;  // Height is 736, but 667 when zoomed.
    }
    return NO;
}

Примечание: Если вы проверяете для iPhone 6 Plus, чтобы настроить пользовательский интерфейс, то не полагайтесь на .nativeScale, потому что имитатор и фактическое устройство дают разные результаты. Из-за комментария ниже. Масштаб-это CGFloat, и поэтому код не должен проверять равенство, потому что некоторые значения поплавков могут никогда не быть равными.


после добавления Запуск вы можете использовать новые размеры iPhone, в противном случае ваше приложение будет по-прежнему выглядят масштабируется.

обновлено для новых iPhone X, X и X Max

размер iPhone X Max с @3x масштабирование (имя Apple:Super Retina HD 6.5 display"), координатное пространство: 414 x 896 очки и 1242 x 2688 пикселей, 458 ppi, физический размер устройства составляет 3,05 х 6,20 дюйма или 77,4 х 157,5 мм.

let screen = UIScreen.main
print("Screen bounds: \(screen.bounds), Screen resolution: \(screen.nativeBounds), scale: \(screen.scale)")
//iPhone X Max Screen bounds: (0.0, 0.0, 414.0, 896.0), Screen resolution: (0.0, 0.0, 1242.0, 2688.0), scale: 3.0

размер iPhone X С @2x масштабирование (имя Apple:Super Retina HD 6.1 " дисплей), координатное пространство: 414 x 896 очки и 828 x 1792 пикселей, 326 ppi, физический размер устройства составляет 2,98 х 5,94 дюйма или 75,7 х 150,9 мм.

let screen = UIScreen.main
print("Screen bounds: \(screen.bounds), Screen resolution: \(screen.nativeBounds), scale: \(screen.scale)")
//iPhone X Screen bounds: (0.0, 0.0, 414.0, 896.0), Screen resolution: (0.0, 0.0, 828.0, 1792.0), scale: 2.0

размер iPhone X и iPhone X С @3x масштабирование (имя Apple:Super Retina HD 5.8 " дисплей), координатное пространство: 375 x 812 очки и 1125 x 2436 пикселей, 458 ppi, физический размер устройства составляет 2,79 х 5,65 дюйма или 70,9 х 143,6 мм.

let screen = UIScreen.main
print("Screen bounds: \(screen.bounds), Screen resolution: \(screen.nativeBounds), scale: \(screen.scale)")
//iPhone X and X Screen bounds: (0.0, 0.0, 375.0, 812.0), Screen resolution: (0.0, 0.0, 1125.0, 2436.0), scale: 3.0

размер iPhone 8, 7, 6 плюс и iPhone 8, 7, 6S Plus С @ 3x масштабированием (имя Apple:Retina HD 5.5), координатное пространство: 414 x 736 очки и 1242 x 2208 пикселей, 401 ppi, физический размер экрана составляет 2,7 х 4,8 дюйма или 68 x 122 мм:

Screen bounds: {{0, 0}, {414, 736}}, Screen resolution: <UIScreen: 0x7f97fad330b0; bounds = {{0, 0}, {414, 736}}; 
mode = <UIScreenMode: 0x7f97fae1ce00; size = 1242.000000 x 2208.000000>>, scale: 3.000000, nativeScale: 3.000000

размер iPhone 6 и iPhone 6S С @ 2x масштабированием (имя Apple:Retina HD 4.7), координатное пространство: 375 x 667 очки и 750 x 1334 пикселей, 326 ppi, физический размер экрана составляет 2,3 х 4,1 дюйма или 58 x 104 мм:

Screen bounds: {{0, 0}, {375, 667}}, Screen resolution: <UIScreen: 0x7fa01b5182d0; bounds = {{0, 0}, {375, 667}}; 
mode = <UIScreenMode: 0x7fa01b711760; size = 750.000000 x 1334.000000>>, scale: 2.000000, nativeScale: 2.000000

и iPhone 5 для сравнения это 640 х 1136,iPhone 4 640 x 960.

Примечание: загрузить LaunchImages в противном случае приложение будет работать масштабируется и не показывает правильное масштабирование или размеры экрана.

Comparing iPhone 6 and 6 Plus

Если вы предпочитаете макросы вот те, которые вы можете использовать, чтобы различать модели iPhone. Они основаны на значениях точек.

#define IS_IPHONE_4 (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)480) < DBL_EPSILON)
#define IS_IPHONE_5 (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON)
#define IS_IPHONE_6 (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)667) < DBL_EPSILON)
#define IS_IPHONE_6_PLUS (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)736) < DBL_EPSILON)

Я использую следующий код, чтобы определить, какое устройство работает (это немного быстро и грязно, но это делает трюк)

if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ){

    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    if( screenHeight < screenWidth ){
        screenHeight = screenWidth;
    }

    if( screenHeight > 480 && screenHeight < 667 ){
        NSLog(@"iPhone 5/5s");
    } else if ( screenHeight > 480 && screenHeight < 736 ){
        NSLog(@"iPhone 6");
    } else if ( screenHeight > 480 ){
        NSLog(@"iPhone 6 Plus");
    } else {
        NSLog(@"iPhone 4/4s");
    }
}

(это работает только тогда, когда iPhone 6 / 6 Plus включен, добавив соответствующие заставки)

на физическом устройстве границы главного экрана iPhone 6 Plus составляют 2208x1242, а nativeBounds-1920x1080. Для изменения размера физического дисплея используется аппаратное масштабирование.

на симуляторе границы главного экрана iPhone 6 Plus и nativeBounds-это 2208x1242.

другими словами... Видео, OpenGL и другие вещи, основанные на CALayers, которые имеют дело с пикселями, будут иметь дело с реальным буфером кадров 1920x1080 на устройстве (или 2208x1242 на sim-карте). Вещи работа с точками в UIKit будет иметь дело с границами 2208x1242 (x3) и масштабироваться соответствующим образом на устройстве.

У симулятора нет доступа к тому же оборудованию, которое выполняет масштабирование на устройстве, и нет действительно большого преимущества для моделирования его в программном обеспечении, поскольку они будут давать разные результаты, чем аппаратное обеспечение. Таким образом, имеет смысл установить nativeBounds главного экрана моделируемого устройства в границы основного физического устройства экран.

iOS 8 добавила API в UIScreen (nativeScale и nativeBounds), чтобы разработчик мог определить разрешение CADisplay, соответствующее UIScreen.

Проверьте обновленный список на wiki, там я получил 7,2 для iPhone 6 и 7,1 для iPhone 6 plus.

вы можете обнаружить iPhone 6 Plus на основе его собственного масштаба, используя этот макрос:

#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)

ответ Ханнеса Сверриссона почти правильный. Система координат iPhone 6 на самом деле больше, чем 5s, используя его код:

UIScreen *mainScreen = [UIScreen mainScreen];
NSLog(@"Screen bounds: %@, Screen resolution: %@, scale: %f, nativeScale: %f",
      NSStringFromCGRect(mainScreen.bounds), mainScreen.coordinateSpace, mainScreen.scale, mainScreen.nativeScale);

система координат для приложений, обеспечивающих правильные изображения запуска являются:

размер для iPhone 6 (Retina HD 4.7) с @ 2x масштабированием, координатное пространство: 375 x 667 и 750 x 1334 фактические точки:

Screen bounds: {{0, 0}, {375, 667}}, Screen resolution: <UIScreen: 0x7fa01b5182d0; bounds = {{0, 0}, {375, 667}}; 
mode = <UIScreenMode: 0x7fa01b711760; size = 750.000000 x 1334.000000>>, scale: 2.000000, nativeScale: 2.000000

размер для iPhone 6 Plus (Retina HD 5.5) с масштабированием @3x, координатное пространство: 414 x 736 и 1242 x 2208 фактический очки:

Screen bounds: {{0, 0}, {414, 736}}, Screen resolution: <UIScreen: 0x7f97fad330b0; bounds = {{0, 0}, {414, 736}}; 
mode = <UIScreenMode: 0x7f97fae1ce00; size = 1242.000000 x 2208.000000>>, scale: 3.000000, nativeScale: 3.000000

это то, что я использую в своем приложении с iOS 8:

window=[[[UIApplication sharedApplication] windows] firstObject];

NSLog(@"screenHeight=%f width=%f",window.frame.size.height,window.frame.size.width);

if (window.frame.size.height == 480) {

        do stuff here... 
    }

до Xcode6 / iOS 8 я использовал это, но границы экрана не работают должным образом с изменяемым размером симулятором или, по крайней мере, это не было в бета-версиях Xcode6...

CGRect screenBounds=[[UIScreen mainScreen] bounds];

if (screenBounds.size.height >= 568) {

do stuff here...

}

мне пришлось обнаружить iPhone 6 Plus в приложении, построенном с iOS 7. Поскольку nativeScale недоступен на [uiscreen mainScreen] я попытался использовать [uiscreen mainScreen] scale], но это только что вернуло 2.0. Поэтому я придумал это решение для обнаружения iPhone 6 Plus на iOS 7 (также должен работать на iOS 8):

-(BOOL)iPhone6Plus{
BOOL isiPhone6Plus = NO;
SEL selector = NSSelectorFromString(@"scale");
if ([[UIScreen mainScreen] respondsToSelector:selector]) {
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                                [[[UIScreen mainScreen] class] instanceMethodSignatureForSelector:selector]];
    [invocation setSelector:selector];
    [invocation setTarget:[UIScreen mainScreen]];
    [invocation invoke];
    float returnValue;
    [invocation getReturnValue:&returnValue];
    if (returnValue == 3.0) {
        isiPhone6Plus = YES;
    }
    NSLog(@"ScaleFactor %1.2f", returnValue);
}
return isiPhone6Plus;

}

интересная часть этого кода заключается в том, что если я использую NSInvocation, возвращаемое значение селектора шкалы будет 3.0. Вызов этого метода непосредственно на iOS 7 возвращает 2.0.

все три устройства имеют (почти) одинаковое количество точек на дюйм. Таким образом, ваши изображения будут автоматически иметь одинаковый физический размер.

использовать [[UIScreen mainScreen] bounds] чтобы получить общее количество точек на экране. Делим на 163, чтобы получить приблизительный размер в дюймах, если вы действительно этого хотите.

обратите внимание, что 6+ не возвращает 1080p, потому что он не отображается в буфер 1080p. Он делает так, что выход составляет примерно 160 точек на дюйм, используя @3x активы.

не нужно сомневаться.

например, если вы пишете этот код:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 163, 163)];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];

вы получите представление, которое в значительной степени тот же физический размер - один квадратный дюйм - на всех устройствах iOS.

Apple уже сделала тяжелую работу, так что вам не придется.

для меня это работает для меня

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
    UIStoryboard *storyBoard;

    CGSize result = [[UIScreen mainScreen] bounds].size;
    CGFloat scale = [UIScreen mainScreen].scale;
    result = CGSizeMake(result.width * scale, result.height * scale);

    if(result.height == 1136){
        storyBoard = [UIStoryboard storyboardWithName:@"Main_iPhone_5" bundle:nil];
        UIViewController *initViewController = [storyBoard instantiateInitialViewController];
        [self.window setRootViewController:initViewController];

    } else if(result.height == 1334){
        storyBoard = [UIStoryboard storyboardWithName:@"Main_iPhone_6" bundle:nil];
        UIViewController *initViewController = [storyBoard instantiateInitialViewController];
        [self.window setRootViewController:initViewController];

    } else if(result.height == 2208){
        storyBoard = [UIStoryboard storyboardWithName:@"Main_iPhone_6_plus" bundle:nil];
        UIViewController *initViewController = [storyBoard instantiateInitialViewController];
        [self.window setRootViewController:initViewController];

    } else if(result.height == 960){
        storyBoard = [UIStoryboard storyboardWithName:@"Main_iPhone_4" bundle:nil];
        UIViewController *initViewController = [storyBoard instantiateInitialViewController];
        [self.window setRootViewController:initViewController];

    }

} else {

    UIStoryboard *storyBoard;

    storyBoard = [UIStoryboard storyboardWithName:@"Main_iPad" bundle:nil];
    UIViewController *initViewController = [storyBoard instantiateInitialViewController];
    [self.window setRootViewController:initViewController];

}

это гарантированно компилируется в xcode 5 (xocde 6 на данный момент все еще шелушится, и вы не можете отправить ipa в itunes connect для утверждения app store с помощью бета-версии программного обеспечения, которое xcode 6 прямо сейчас)

дело в том, что xcode 5 не распознает nativeScale селектор.. это, как вы можете сделать это во время выполнения:

+ (BOOL)isIphone6Plus
{
    SEL selector = NSSelectorFromString(@"nativeScale");
    if ([[UIScreen mainScreen] respondsToSelector:selector]) {
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                                        [[[UIScreen mainScreen] class] instanceMethodSignatureForSelector:selector]];
            [invocation setSelector:selector];
            [invocation setTarget:[UIScreen mainScreen]];
            [invocation invoke];
            float returnValue;
            [invocation getReturnValue:&returnValue];
            NSLog(@"::: this is native scale %f", returnValue);
            return (returnValue == 3.0f);
    } else {
        // iphone 6 plus come prepackaged with iOS8.. 
        // so if the phone doesn't know what nativeScale means
        // it's not an iphone6plus phone
        return NO;
    }
}

интересная вещь, которую нужно помнить при чтении размеров экрана на моем iPhone 6 Plus было то, что когда у вас есть он установлен в "увеличенном" режиме он будет отображаться как высота iPhone 6 (667) и когда у вас есть он установлен в "стандарт" он будет отображаться как (736). На самом деле это не имеет значения, но если вы специально хотите узнать тип устройства по какой-то причине ( возможно, отчетность), это может обмануть вас.

посмотреть этой.

вот обновленный исходный код, который вы используете этой.

добавлены модели iPhone 6 и iPhone 6 Plus.

одна важная вещь, которую выше ответы не учитывают, это тот факт, что в iOS7 и ниже, когда вы проверяете [[UIScreen mainScreen] bounds] для границ экрана он всегда перечисляет ширину и высоту как одно и то же независимо от того, в какой ориентации находится телефон. Поэтому, если это iPhone5 в ландшафтном режиме, он все равно будет отображать ширину как 320 и высоту как 568. В iOS8 это изменилось, теперь, если тот же iPhone5 находится в ландшафте, он будет отображать ширину как 568 и высоту как 320. Ниже приведены методы, которые учитывают это:

+ (BOOL) deviceHasFourInchScreen
{
    return [DeviceType deviceHasScreenWithIdiom:UIUserInterfaceIdiomPhone scale:2.0 height:568.0];
}

+ (BOOL) deviceHasFourPointSevenInchScreen
{
    return [DeviceType deviceHasScreenWithIdiom:UIUserInterfaceIdiomPhone scale:2.0 height:667.0];
}

+ (BOOL) deviceHasFivePointFiveInchScreen
{
    return [DeviceType deviceHasScreenWithIdiom:UIUserInterfaceIdiomPhone scale:3.0 height:736.0];
}

+ (BOOL) deviceHasScreenWithIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom scale:(CGFloat)scale height:(CGFloat)height
{
    CGRect mainScreenBounds = [[UIScreen mainScreen] bounds];
    CGFloat mainScreenHeight;

    if ([OperatingSystemVersion operatingSystemVersionLessThan:@"8.0"])
    {
        mainScreenHeight = mainScreenBounds.size.height;
    }
    else
    {
        mainScreenHeight = (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) ? mainScreenBounds.size.width : mainScreenBounds.size.height;
    }

    if ([[UIDevice currentDevice] userInterfaceIdiom] == userInterfaceIdiom && [[UIScreen mainScreen] scale] == scale && mainScreenHeight == height)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

также здесь представлены сопутствующие методы класса OperatingSystem:

+ (NSString *) currentOperatingSystemVersion
{
    return [[UIDevice currentDevice] systemVersion];
}
+ (BOOL) operatingSystemVersionLessThanOrEqualTo:(NSString *) operatingSystemVersionToCompare
{
    return ([[self currentOperatingSystemVersion] compare: operatingSystemVersionToCompare options:NSNumericSearch] != NSOrderedDescending);    
}

Swift 4

if(kSize.width == 320){
             //iphone se
}else if(kSize.width == 375 && kSize.height == 667){
             //iphone 7 / 8
}else if(kSize.width == 375){
            //iphone x
}else if(kSize.width == 414){
           //iphone 7 plus/ 8 plus
}

kSize-это экран CGSize

пусть kSize = UIScreen.главный.границы.размер