iPhone 5 (와이드 스크린 장치)를 감지하는 방법?


300

방금 XCode 4.5 GM으로 업그레이드했으며 스토리 보드의 뷰 컨트롤러에 '4 "Retina 크기를 적용 할 수 있음을 알게되었습니다.

이제 iPhone 4와 5에서 모두 실행되는 응용 프로그램을 만들려면 모든 창을 두 번 작성해야하지만 사용자에게 3.5 "또는 4"화면의 iPhone이 있는지 여부를 감지 한 다음 전망.

어떻게해야합니까?


2
모든 "창"을 두 번 만들 필요는 없습니다. 화면 크기와 정확히 일치하는 것으로 만 릴레이 아웃해야합니다. 해결책은 다소 명백한 것 같습니다. 단순히 창 크기를 확인하고 반환 된 크기에 따라 사례 결정을 추가하십시오.
까지

1
글쎄, 기본적으로 사실이지만 가로 화면으로 할 수있는 것처럼 여분의 화면 크기를 완전히 다른 방식으로 사용하고 싶습니다.
Finn Gaida

이 URL을 확인하십시오 : stackoverflow.com/questions/4779221/…
ios_av

이 질문은 새로운 장치에 따라 업데이트되어야합니까? 예 : "화면 크기별로 iOS 기기를 감지하는 방법"?
hfossli

답변:


467

우선, 새 화면에 맞게 모든보기를 다시 작성하거나 다른 화면 크기에 대해 다른보기를 사용해서는 안됩니다.

iOS 의 자동 크기 조정 기능을 사용 하여보기를 조정하고 모든 화면 크기를 조정할 수 있습니다.

그리 어렵지 않습니다 . 그것에 관한 문서 를 읽으십시오 . 시간을 많이 절약 할 수 있습니다.

iOS 6은 이에 관한 새로운 기능도 제공합니다. Apple 개발자 웹 사이트
에서 iOS 6 API 변경 로그 를 읽으십시오 .
그리고 새로운 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 화면에 최적화되지 않은 경우 (Default-568h@2x.png 이미지 누락)이 매크로는 작동하지 않습니다. 화면 크기는 여전히 320x480입니다. 사례.

최적화되지 않은 앱에서 iPhone 5를 감지하려는 이유를 알 수 없으므로 이것이 문제가 될 수 있다고 생각하지 않습니다.

중요-iOS 8 지원

iOS 8 bounds에서 UIScreen클래스 의 속성은 이제 장치 방향을 반영합니다 .
따라서 이전 코드는 기본적으로 작동하지 않습니다.

이 문제를 해결 하려면 방향에 따라 변경되지 않고 세로 방향 모드를 기반으로하기 때문에 nativeBounds대신 새 속성을 사용하면 bounds됩니다.
치수는 nativeBounds픽셀 단위로 측정되므로 iPhone 5의 경우 높이는 568 대신 1136 입니다.

iOS 7 이하를 대상으로하는 경우 nativeBoundsiOS 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 )
파비안 Kreiser

28
@ H2CO3 : DBL_EPSILON여기서 ==비교는 필요 하지 않으며 비교는 실패 하지 않습니다. 부동 소수점 값을 정확한 숫자로 표현할 수없는 경우 (예 1.0/3.0*3.0를 들어) 부동 소수점 값을이 방법으로 비교하면됩니다 . 자세한 내용이 기사 를 읽으십시오 ;)
AliSoftware

2
이 답변은 정확하지 않습니다. 왜 그렇게 많은 엄지 손가락을 얻었습니까? 높이 만 사용하여 와이드 스크린인지 확인할 수 없습니다. 친구 ...
OMGPOP

5
추가 할 수 있습니다. 시뮬레이터에서이 작업을 수행하려면 다음을 사용하십시오. @ "iPhone Simulator"]))
david

31
이 답변은 광기입니다. ==와 함께 이러한 특정 종류의 부동 소수점 (실제로 Apple이 항상 알고 있음을 알고 있어야 함)을 비교하지 않는 것이 좋습니다. ==는 의미가없고 지나치게 복잡합니다. 또한 iPhone 감지에 UI_USER_INTERFACE_IDIOM ()을 사용하는 것이 장치와 시뮬레이터 모두에서 잘 작동하므로 UIDevice 접근 방식보다 빠를 수 있다고 생각합니다. #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Ricardo Sanchez-Saez

232

SDK와 OS의 모든 조합에 대해 테스트 및 설계되었습니다.

빠른

iPad 유형이 추가되었습니다. iPad 2 및 iPad mini는 레티 나 이외의 iPad입니다. 위의 아이 패드 미니 2, 아이 패드 3, 4 있지만, 아이 패드 에어, 에어 2 에어 3, 아이 패드 프로 9.7은 1024 아이 패드 프로의 동일한 논리 해상도를 가지고하는 것은 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이 확대 모드 인 경우 UI는 iPhone 5의 확대 버전입니다. 이러한 기능은 장치 유형을 결정하는 것이 아니라 디스플레이 모드이므로 iPhone 5가이 예에서 원하는 결과입니다.

목표 -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이 확대 모드 인 경우 UI는 iPhone 5의 확대 버전입니다. 이러한 기능은 장치 유형을 결정하는 것이 아니라 디스플레이 모드이므로 iPhone 5가이 예에서 원하는 결과입니다.


1
iPhone 5는 새로운 기본 이미지없이 일반 480x320 화면 크기를보고합니다. 나에게 이것은 원하는 행동이다.
hfossli

3
아마도 유용한 추가 기능은 #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)iPhone4와 iPhone5 그리고 iPad Retina와 레티 나 이외의 차이점을 결정하는 데 도움 이 될 것입니다
bshirley

1
동의하지 않습니다. '와이드 스크린'용어는 빨리 구식이므로 생략해야한다고 생각합니다.
hfossli

1
@Dvole 그것이 iOS 8의 동작 방식입니다. 사용 SCREEN_MAX_LENGTH아이폰 5의 모든 회전에서 568을 얻기 위해
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
매크로 나 함수에 물건을 넣지 않는 것은 건조하지 않는 경향이 있습니다 ... 지금
부터이

예, 그러나 위와 같이 매크로를 정의하면 더 편리하고 쉽습니다. 매번 쓸 경우 붙여 넣을 필요가 없습니다.
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
Linh Nguyen

아이폰 6, 6 플러스 화면 크기에 대한 계정 아래에 답을 업데이트
샘 B

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"

그것은 단지 나를 위해 작동하지 않습니다 아이폰 5는 4 아이폰 6 + 결정하지 않았다 아 아 나는 그것을 가로로 높이 변경해야합니다 :)
ColdSteel

앱이 가로 모드 인 경우 result.height를 result.width로 변경해야합니다.
Sam B

흠 .. 아이폰 4 (iOS 6.0)에서 스왑하지 : (iOS 6.0 prob 또는 아이폰 4 일 수 있습니까?
ColdSteel

좋아, iOS 8 이상에서만 바뀐보기를 확인했다
ColdSteel

iPhone 6의 높이 = 568
MaxEcho

15

나는 C 함수에 Macmade하여 매크로를 놓고, 그것을 감지하기 때문에 제대로 이름을 자유를 촬영했습니다 와이드 스크린 가용성NOT 반드시 아이폰 5.

매크로에 프로젝트에 Default-568h@2x.png가 포함되어 있지 않은 경우 iPhone 5에서 실행되는 것을 감지하지 못합니다 . 새로운 기본 이미지가 없으면 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 일 수 있습니다 . 또한 컴파일러의 옵티마이 저가 좋은 아이디어라고 생각하는 곳과 그것이 허용 가능한지 알 수있는 곳 (예 : 함수가 동일한 모듈에 있음)에 인라인됩니다. 함수를 통해 이와 같은 것을 구현하면 때로는 추가 유형 검사가 발생할 수 있습니다.
Ivan Vučica

4
성능 관련 질문은 렌더 루프 동안 왜이 검사를 수천 번 실행 하시겠습니까? 그렇지 않으면 성능은 문제가되지 않으며 명확하며 부작용의 중요성을 피합니다.
LearnCocos2D

나는 매크로가 아닌 별도의 기능을 좋아하기 때문에 +1 을주었지만 실제로 정확하지 않거나 완전하지 않다는 것을 지적해야합니다. 와이드 스크린을 감지하려면 화면 높이를 보지 마십시오 . 대신 가로 세로 비율을보고 가로 세로 비율이 16 : 9 이상인 경우에만 true를 반환하십시오.
Todd Lehman

11

다음은 우리의 코드 입니다 .iphone4, iphone5, ipad, iphone6, iphone6p, 장치 또는 시뮬레이터에 상관없이 ios7 / ios8에 전달 된 테스트입니다.

#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로 똑바로 복사하고 붙여 넣기했으며 전화가 iOS 8.3을 실행하는 6 플러스라는 것을 알고 있습니다.
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

Samrat Mazumdar의 답변에서 차용 한 장치 화면 크기를 추정하는 간단한 방법이 있습니다. 최신 장치에서는 작동하지만 모든 장치를 추측하는 것처럼 미래 장치에서는 실패 할 수 있습니다. 장치가 미러링되는 경우에도 혼동됩니다 (미러 된 화면 크기가 아닌 장치의 화면 크기를 반환 함)

#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의 개정이 필요합니다.
Daniel

예, iPad mini의 해상도는 iPad2와 동일하므로이 방법으로는 효과가 없습니다. 확실하지 ... 지금 그 사건을 처리하는 방법
제프 헤이

1
넌 안 돼 "iPad 2,5"구매에 대한 장치 식별자를 확인할 수 있습니다. 또한 Wi-Fi 전용 버전, GSM 및 CDMA 인 2,6 및 2,7도 확인해야합니다. 그러나 이는 다음 iPad mini가 출시 될 것이며 사전에 알 수없는 식별자로 하드 코드로 업데이트해야한다는 것을 의미합니다. 더 작은 화면에 대해 "최적화"하려고하지 않아야하기 때문에 iPad mini를 사용하는시기를 대륙에서 알 수 없습니다.
Daniel

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

이것은 백 번 대답되었지만이 솔루션은 나에게 가장 효과적이며 새로운 장치가 도입되고 크기가 정의되지 않은 경우 문제를 해결하는 데 도움이되었습니다.

스위프트 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) 디스플레이가 있습니다.
Vaibhav Sharma

따라서 IS_RETINAiPhone 6 plus에서 테스트 한 경우 1x 코드가 실행됩니까?
vikingosegundo

이 링크를 참조하십시오. stackoverflow.com/questions/25756589/…
Vaibhav Sharma

1
당신은 그것을 얻지 못합니다 : 당신의 규칙은 항복 @1x해야합니다 @3x. 어쨌든 : 당신은 단순히 복사 및 붙여 넣기로 : -1
vikingosegundo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.