Обнаружение размеров экрана 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 ответов:
первый экран будет экран устройства, обратите внимание, что запуск изображения для новых телефонов должны быть добавлены раньше, в противном случае приложение работает в режиме масштабирования для старых приложений : Вот код, который я использовал, чтобы проверить это. Примечание: это работает только с версией 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 в противном случае приложение будет работать масштабируется и не показывает правильное масштабирование или размеры экрана.
Если вы предпочитаете макросы вот те, которые вы можете использовать, чтобы различать модели 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); }