Как определить iPhone 5 (широкоэкранные устройства)?


300

Я только что обновился до XCode 4.5 GM и обнаружил, что теперь вы можете применить размер «4» Retina к вашему контроллеру представления в раскадровке.

Теперь, если я хочу создать приложение, которое работает как на iPhone 4, так и на 5, я, конечно, должен создать каждое окно дважды, но я также должен определить, есть ли у пользователя iPhone с экраном 3,5 или 4 дюйма, и затем применить Посмотреть.

Как мне это сделать?


2
Вам не нужно строить каждое «окно» дважды. Только те, которые должны точно соответствовать размеру экрана, должны быть переназначены. Решение кажется довольно очевидным, просто проверьте размеры окна и добавьте решение по случаю на основе возвращенного размера.
до

1
Ну, в принципе это правда, но я хочу использовать дополнительный размер экрана совершенно по-другому, как вы могли бы сделать с пейзажным экраном.
Финн Гайда

Проверьте этот URL: stackoverflow.com/questions/4779221/…
ios_av

Нужно ли обновлять этот вопрос в соответствии с новыми устройствами? Например, «Как определить устройство iOS по размеру экрана»?
hfossli

Ответы:


467

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

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

Это не очень сложно, почитайте документацию об этом. Это сэкономит вам много времени.

iOS 6 также предлагает новые функции по этому поводу.
Обязательно прочтите журнал изменений API iOS 6 на веб-сайте Apple Developer.
И проверьте новые возможности 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 )

Использование fabs с epsilon здесь для предотвращения ошибок точности при сравнении чисел с плавающей запятой, как указано в комментариях H2CO3.

Так что теперь вы можете использовать его в стандартных операторах if / else:

if( IS_IPHONE_5 )
{}
else
{}

Edit - лучшее обнаружение

Как утверждают некоторые люди, это только обнаруживает широкоэкранный , а не реальный 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), так как размер экрана в таком случае будет 320x480. случай.

Я не думаю, что это может быть проблемой, так как я не понимаю, почему мы хотели бы обнаружить iPhone 5 в неоптимизированном приложении.

ВАЖНО - поддержка iOS 8

В iOS 8 boundsсвойство UIScreenкласса теперь отражает ориентацию устройства .
Очевидно, что предыдущий код не будет работать из коробки.

Чтобы исправить это, вы можете просто использовать новое nativeBoundsсвойство вместо того bounds, чтобы оно не изменялось в зависимости от ориентации, и поскольку оно основано на портретном режиме.
Обратите внимание, что размеры nativeBoundsизмеряются в пикселях, поэтому для iPhone 5 высота будет 1136 вместо 568.

Если вы также ориентируетесь на iOS 7 или ниже, обязательно используйте функцию обнаружения функций, поскольку вызов nativeBoundsдо iOS 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, используйте соответствующие размеры экрана.


7
Это неправильно, вам придется использовать#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Фабиан Крейзер

28
@ H2CO3: обратите внимание, что здесь сравнение DBL_EPSILONне является обязательным, и ==сравнение не будет неудачным: необходимо проводить сравнение с использованием различий таким образом, только если значение с плавающей запятой не может быть выражено как точное число (как, 1.0/3.0*3.0например,). Прочитайте эту статью для получения дополнительной информации;)
AliSoftware

2
этот ответ не верен. почему он поднял так много больших пальцев? Вы не можете использовать только высоту, чтобы определить, широко ли она. чувак ...
OMGPOP

5
Могу ли я добавить: Если вы хотите, чтобы это работало с симулятором, используйте это: #define IS_IPHONE (([[[[UIDevice currentDevice] модель] isEqualToString: @ "iPhone"]) || ([[[[UIDevice currentDevice] модель] isEqualToString: @ "iPhone Simulator"]))
Дэвид

31
Этот ответ - безумие. Этот материал о том, что мы не рекомендуем сравнивать эти конкретные типы чисел с плавающей точкой (которые на самом деле являются - и если вы знаете, что Apple должна знать, что всегда будут - целыми числами) с == - это бессмыслица и усложняет вещи. Кроме того, я думаю, что лучше использовать UI_USER_INTERFACE_IDIOM () для обнаружения iPhone, поскольку он отлично работает как на устройстве, так и на симуляторе (и это может быть быстрее, чем подход UIDevice). Это просто отлично работает и намного проще для чтения: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Рикардо Санчес-Саез

232

Протестировано и разработано для любой комбинации SDK и ОС:

стриж

Добавлены типы iPad. iPad 2 и iPad mini не являются сетевыми iPad. В то время как iPad Mini 2 и выше, iPad 3, 4, iPad Air, Air 2, Air 3 и iPad Pro 9.7 имеют одинаковое логическое разрешение 1024. У iPad Pro максимальная длина 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 находится в режиме увеличения, пользовательский интерфейс является увеличенной версией 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 находится в режиме увеличения, пользовательский интерфейс является увеличенной версией iPhone 5. Эти функции определяют не тип устройства, а режим отображения, поэтому iPhone 5 является желаемым результатом в этом примере.


1
iPhone 5 будет отображать обычный размер экрана 480x320 без нового изображения по умолчанию. Для меня это желаемое поведение.
hfossli

3
Возможно полезным дополнением является то, #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)что поможет определить разницу между iPhone4 и iPhone5 и iPad Retina и non-retina
bshirley

1
Я не согласен. Я думаю, что «широкоэкранная» терминология должна быть опущена, поскольку она быстро устарела.
hfossli

1
@Dvole, как ведет себя iOS 8. Используйте, SCREEN_MAX_LENGTHчтобы получить 568 во всех поворотах на iPhone 5.
hfossli

1
@MattParkins Я бы предложил использовать более надежные проверки моделей stackoverflow.com/questions/13366976/… .
hfossli

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
    }
}

1
ха-ха, коротко и simpel, сделал то же самое :) удары вверх для поддержания над головой низко! положить вещи в макрос не сложно ...
benjamin.ludwig

2
Ну, если вы не помещаете вещи в макрос или функции, это может быть СУХОЙ ... С того момента, как вам нужно сделать эту проверку более одного раза ...
hfossli

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

Спасибо, Ты спас мне жизнь: D, но я не знаю, почему Макрос: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds] .size.height == 568.0) ==> Не работал в симуляторе iOS 7.1, до что я все еще работаю над XCode 4.6. OMG iOS 7.1 и Xcode 5
Линь Нгуен

обновленный ответ ниже, чтобы учесть iPhone 6 и 6 плюс размеры экрана
Сэм Б

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"

это просто не работает для меня iPhone 5 решил, так как 4 iPhone 6+ не решил вообще О, я понял, я в ландшафте, я должен изменить высоту с шириной :)
ColdSteel

если ваше приложение находится в ландшафтном режиме, убедитесь, что вы изменили result.height на result.width
Сэм Б.

хм .. на iPhone 4 (iOS 6.0) он не
поменялся

Хорошо, я проверил вид, поменялся местами только в iOS 8 и выше
ColdSteel

iPhone 6 дает рост = 568
MaxEcho

15

Я взял на себя смелость поместить макрос от Macmade в функцию C и правильно назвать его, потому что он обнаруживает широкоэкранную доступность и НЕ обязательно iPhone 5.

Макрос также не обнаруживает запуск на iPhone 5 в случае, если проект не включает Default-568h@2x.png . Без нового изображения по умолчанию iPhone 5 будет отображать обычный размер экрана 480x320 (в пунктах). Таким образом, проверка не только для широкоэкранной доступности, но и для включения широкоэкранного режима .

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}

Я все еще предпочитаю макросы по соображениям производительности. Пожалуйста, смотрите редактирование моего ответа. Также проверяет модель.
Macmade

1
Вы также правы, говоря, что iPhone 5 будет отображать обычный экран размером 480x320 без нового изображения по умолчанию. Но я думаю, что нет смысла обнаруживать iPhone 5 в неоптимизированном приложении. :)
Macmade

@Macmade Действительно, в этом нет никакого смысла, но хорошо иметь в виду, если обнаружение не работает. Также функции могут быть inlined. Они также будут указаны там, где оптимизатор компилятора считает, что это хорошая идея, и где он может знать, что это допустимо (например, функция находится в том же модуле). Реализация подобных вещей через функцию может иногда приводить к дополнительной проверке типов.
Иван Вучица

4
Вопрос, связанный с производительностью, заключается в том, почему вы выполняете эту проверку тысячи раз во время цикла рендеринга? В противном случае производительность не является проблемой и ясностью и позволяет избежать побочных эффектов большей важности.
LearnCocos2D

Я дал вам +1 за это, потому что мне нравится отдельная функция, а не макрос, но я должен отметить, что она не совсем правильная или полная. Чтобы обнаружить широкоформатный экран, не смотрите на высоту экрана. Вместо этого посмотрите на соотношение сторон и верните true, только если соотношение сторон больше или равно 16: 9.
Тодд Леман

11

Вот наши коды, тест пройден на ios7 / ios8 для iphone4, iphone5, ipad, iphone6, iphone6p, независимо от устройства или симулятора:

#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 )

Я тестирую на iPhone 6P и мое утверждение if попадает в состояние IS_IPHONE_5? Как это может быть, ваш код выглядит хорошо? Я сделал прямое копирование и вставку с простым if / else, и я знаю, что мой телефон 6+ работает под управлением iOS 8.3.
Почему

7

Я использовал ответ Хфоссли и перевел его на Свифт

let IS_IPAD = UIDevice.currentDevice().userInterfaceIdiom == .Pad
let IS_IPHONE = UIDevice.currentDevice().userInterfaceIdiom == .Phone
let IS_RETINA = UIScreen.mainScreen().scale >= 2.0

let SCREEN_WIDTH = UIScreen.mainScreen().bounds.size.width
let SCREEN_HEIGHT = UIScreen.mainScreen().bounds.size.height
let SCREEN_MAX_LENGTH = max(SCREEN_WIDTH, SCREEN_HEIGHT)
let SCREEN_MIN_LENGTH = min(SCREEN_WIDTH, SCREEN_HEIGHT)

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

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))

5
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}

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
}

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


2

Исходя из ответа Самрата Мазумдара, вот краткий метод, который оценивает размер экрана устройства. Он работает с последними устройствами, но может не работать на будущих (как и все методы угадывания). Это также может привести к путанице, если устройство зеркально отражается (возвращает размер экрана устройства, а не размер зеркального экрана)

#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
    }
} 

Нужна ревизия для iPad mini, которую, я не думаю, вы сможете определить в этом поместье.
Даниэль

Да, iPad mini имеет то же разрешение, что и iPad2, поэтому этот метод для этого не работает. Не уверен, как справиться с этим делом прямо сейчас ...
Джефф Хэй

1
Ты не должен. Вы можете проверить идентификатор устройства для «iPad 2,5», также вам нужно проверить на 2,6 и 2,7 - версию только для Wi-Fi, GSM и CDMA. Но это означает, что выйдет следующий iPad mini, и вам нужно будет обновить жесткий код до тех идентификаторов, которые вы не могли знать заранее. Вы не можете постоянно знать, когда вы находитесь на iPad mini, потому что на самом деле вы не должны пытаться «оптимизировать» для меньшего экрана
Даниэль

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)

2

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

#define IS_WIDESCREEN ( [ [ UIScreen mainScreen ] bounds ].size.height == 568  )
#define IS_IPHONE ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPhone"].location != NSNotFound)
#define IS_IPAD ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPad"].location != NSNotFound)
#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

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;

}

iPhone5 = FALSE;не
требуется,

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

     }

1

Полагаться на размер неправильно на многих уровнях. Как насчет того, чтобы спросить систему?

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

Взято из Лучший способ определить тип оборудования, iPhone4 или iPhone5? , edzio27 ответ.


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

1

Если проект создан с использованием Xcode 6, используйте указанный ниже код для обнаружения устройств.

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136){
            printf("Device Type : iPhone 5,5S/iPod 5 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1334){
            printf("Device Type : iPhone 6 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 2208){
            printf("Device Type : iPhone 6+ ");

        }
    }
}else{
    printf("Device Type : iPad");
}

Если проект был создан в Xcode 5 и открыт в Xcode 6, используйте указанный ниже код для обнаружения устройств (этот код работает, если не назначены изображения для запуска iPhone 6,6+).

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
       if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s");
            appType=1;
        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136 || [[UIScreen mainScreen] nativeBounds].size.height == 1704){
            printf("Device Type : iPhone 5,5S,6,6S/iPod 5 ");
            appType=3;
        }
    }
}else{
    printf("Device Type : iPad");
    appType=2;
}

Если вы все еще используете Xcode 5 все вместе, используйте следующий код для обнаружения устройств (iPhone 6 и 6+ не будут обнаружены)

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] bounds].size.width,(int)[[UIScreen mainScreen] bounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        CGFloat scale = [UIScreen mainScreen].scale;
        result = CGSizeMake(result.width * scale, result.height * scale);
        if(result.height == 960 || result.height == 480){
            printf("Device Type : iPhone 4,4S ");

        }else if(result.height == 1136){
            printf("Device Type : iPhone 5s/iPod 5");

        }
    }
}else{
    printf("Device Type : iPad");

}

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
        }

1

В Swift 3 вы можете использовать мой простой класс KRDeviceType.

https://github.com/ulian-onua/KRDeviceType

Он хорошо документирован и поддерживает операторы ==,> =, <=.

Например, чтобы определить, имеет ли устройство границы iPhone 6 / 6s / 7, вы можете просто использовать следующее сравнение:

if KRDeviceType() == .iPhone6 {
// Perform appropiate operations
}

Чтобы определить, имеет ли устройство границы iPhone 5 / 5S / SE или более ранних версий (iPhone 4s), вы можете использовать следующее сравнение:

if KRDeviceType() <= .iPhone5 {   //iPhone 5/5s/SE of iPhone 4s
// Perform appropiate operations (for example, set up constraints for those old devices)
}

1

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

Swift 5 Helper:

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 5.5  //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 all iPhones smaller than the plus
}

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


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
}

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;
}

-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) 

iPhone 6 не имеет дисплея сетчатки?
Викингосегунд

iPhone6 ​​имеет дисплей ratina (@ 2X). и iPhone6 ​​plus имеет дисплей HD (@ 3X).
Вайбхав Шарма

Так что, если проверено IS_RETINAна iPhone 6 плюс, выполняется 1x код?
Викингосегундо


1
вы не понимаете: ваши правила уступят @1x, где должны уступить @3x. в любом случае: как вы просто копировать и вставлять: -1
вставляете
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.