Обнаружение размеров экрана 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
являются плюсами? Если у кого-то есть более конкретный способ сказать, что это будет здорово, спасибо.!
Ответы
Ответ 1
Первым экраном будет экран устройства. Обратите внимание, что перед отправкой необходимо добавить изображения запуска для новых телефонов, иначе приложение будет запущено в Zoomed Mode для более старых приложений:
Вот код, который я использовал, чтобы проверить это. Примечание. Это работает только с версией 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, и поэтому код не должен проверять равенство, поскольку некоторые значения float никогда не могут быть равны.
После добавления загрузочных изображений для нового iPhone6 и 6Plus размеры меняются. Они масштабируют старые приложения, чтобы они соответствовали экрану.
Размер для iPhone 6 Plus и iPhone 6S Plus с масштабированием @3x (название Apple: Retina HD 5.5), пространство координат: < сильные > 414 x 736 и 1242 x 2208 пикселей, 401 точек на дюйм, физический размер экрана 2,7 x 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 точек на дюйм, физический размер экрана - 2,3 x 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 x 1136, iPhone 4 640 x 960.
Примечание. Загрузите LaunchImages, иначе приложение будет запускаться с масштабированием и не отображать правильное масштабирование или размеры экрана.
![Comparing iPhone 6 and 6 Plus]()
Ответ 2
Если вы предпочитаете макросы, это те, которые вы можете использовать, чтобы различать модели 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)
Ответ 3
Я использую следующий код, чтобы определить, какое устройство работает (оно немного быстро и грязно, но оно делает трюк)
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 включен, добавив соответствующие заставки)
Ответ 4
На физическом устройстве основные ограничения экрана iPhone 6 Plus - 2208x1242, а nativeBounds - 1920x1080. Существует аппаратное масштабирование для изменения размера на физический дисплей.
В симуляторе основные ограничения экрана iPhone 6 Plus и nativeBounds - это 2208x1242.
Другими словами... Видео, OpenGL и другие вещи, основанные на CALayers, которые имеют дело с пикселями, будут иметь дело с реальным фреймбуфером 1920x1080 на устройстве (или 2208x1242 на симе). Вещи, касающиеся точек в UIKit, будут иметь дело с границами 2208x1242 (x3) и масштабироваться по мере необходимости на устройстве.
Симулятор не имеет доступа к тому же оборудованию, которое делает масштабирование на устройстве, и нет никакой пользы для имитации его в программном обеспечении, поскольку они будут давать разные результаты, чем аппаратное обеспечение. Таким образом, имеет смысл установить для nativeBounds основного экрана имитируемого устройства границы основного экрана физического устройства.
iOS 8 добавил API в UIScreen (nativeScale и nativeBounds), чтобы разработчик смог определить разрешение CAD файла, соответствующего UIScreen.
Ответ 5
Проверьте обновленный список wiki, там я получил 7,2 для iPhone 6 и 7,1 для iPhone 6 плюс.
Ответ 6
Вы можете обнаружить iPhone 6 Plus на основе собственного масштаба, используя этот макрос:
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
Ответ 7
Ответ Ханнес Сверриссон почти правильный. Система координат iPhone 6 на самом деле больше, чем 5 секунд. Используя его код:
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
Ответ 8
Это то, что я использую в своем приложении с 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...
}
Ответ 9
Мне пришлось обнаружить iPhone 6 Plus в приложении, построенном на iOS 7. Поскольку nativeScale недоступен на [UIScreen mainScreen], я попытался использовать масштаб [UIScreen mainScreen]], но это только что вернуло 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.
Ответ 10
Все три устройства имеют (в значительной степени) одинаковое количество точек на дюйм. Таким образом, ваши изображения будут автоматически иметь одинаковый физический размер.
Используйте [[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 уже проделала тяжелую работу, поэтому вам не нужно.
Ответ 11
для меня это работает для меня
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];
}
Ответ 12
Вот обновленный исходный код, который вы используете this.
Добавлены модели iPhone 6 и iPhone 6 Plus.
Ответ 13
это гарантировано скомпилировать в xcode 5 (xocde 6 на этом этапе по-прежнему нечеткий, и вы не можете отправить ipa для подключения itunes для утверждения магазина приложения с помощью бета-версии программного обеспечения, которое теперь имеет 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 not an iphone6plus phone
return NO;
}
}
Ответ 14
Интересная вещь, которую следует помнить при чтении размеров экрана на моем iPhone 6 Plus, заключалась в том, что когда у вас установлен режим "Zoomed", она будет отображаться как высота iPhone 6 (667), и когда вы установите ее на "Стандарт" будет отображаться как (736). Не имеет значения, но если вы специально хотели узнать тип устройства по какой-либо причине (возможно, Reporting), это может вас обмануть.
См. this.
Ответ 15
Одна из основных причин, по которым вышеприведенные ответы не учитываются, заключается в том, что в 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);
}
Ответ 16
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
let kSize = UIScreen.main.bounds.size