Як виявити 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 також пропонує нові функції щодо цього.
Обов’язково прочитайте журнал змін змін 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епсилон, щоб запобігти помилкам точності при порівнянні плаваючих точок, як зазначено в коментарях H2CO3.

Тож відтепер ви можете використовувати його у стандартних операторах if / else:

if( IS_IPHONE_5 )
{}
else
{}

Редагувати - Краще виявлення

Як заявляють деякі люди, це виявляє лише широкоекранний , а не власне 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 (відсутнє зображення за замовчуванням-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 )
Fabian Kreiser

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 є бажаним результатом у цьому прикладі.

Ціль-С

#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 та
неретина

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
Ха-ха, короткий і симпель, зробив те саме :) Пальці за те, щоб утримувати низькі витрати! введення матеріалів у макрос не є викликом ...
benjamin.ludwig

2
Ну, не вкладаючи речі в макро чи функції, схильні не бути БУДИМИ ... З моменту, коли вам потрібно це перевірити не один раз ...
hfossli

Так, але визначити макрос, як показано вище, зручніше і простіше, вам не потрібно вставляти це, якщо ... кожен раз.
Відпочинок

Дякую, ти врятував мені життя: D, але я не знаю, чому Макрос: #define IS_IPHONE_5 (IS_IPHONE && [межі [основного екрана UIScreen]]). що я досі працюю над XCode 4.6. OMG iOS 7.1 та Xcode 5
Linh Nguyen

оновлена ​​відповідь нижче, щоб обліковувати розміри екранів 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 to result.width
Sam B

хм .. на iPhone 4 (iOS 6.0) він не мінявся :( може бути iOS 6.0 prob чи iPhone 4?
ColdSteel

Гаразд, я перевірив перегляд, розміщений лише в 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 за це, тому що мені подобається окрема функція, а не макрос, але я мушу зазначити, що це насправді не правильно чи повно. Щоб виявити широкоекранний, не дивіться на висоту екрана. Натомість подивіться на співвідношення сторін і поверніть істинне, лише якщо співвідношення сторін більше або дорівнює 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 і моє, якщо заява потрапляє в стан IS_IPHONE_5? Як це може бути, ти добре виглядаєш з кодом? Я зробив пряму копію та вставив просту if / else, і я знаю, що у мене телефон 6 плюс під керуванням iOS 8.3.
whyoz

7

Я використав відповідь hfossli і переклав її на Swift

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;є непотрібним, оскільки змінна вже має це значення, якщо її не змінити
mcont

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

Таким чином можна виявити сімейство пристроїв.

    #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. Додайте "Новий файл швидкої" -> 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:

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 немає дисплея сітківки?
vikingosegundo

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

Тож якщо тестується IS_RETINAна iPhone 6 плюс, виконується 1x код?
vikingosegundo

Дивіться це посилання. stackoverflow.com/questions/25756589/…
Vaibhav Sharma

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