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

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

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

어떻게해야합니까?



답변

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

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 이미지 누락)이 매크로는 작동하지 않습니다. 화면 크기는 여전히 320×480입니다. 사례.

최적화되지 않은 앱에서 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를 감지해야하는 경우 해당 화면 크기를 사용하십시오.


답변

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가이 예에서 원하는 결과입니다.


답변

정말 간단한 솔루션

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}


답변

이제 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"


답변

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

매크로에 프로젝트에 Default-568h@2x.png가 포함되어 있지 않은 경우 iPhone 5에서 실행되는 것을 감지하지 못합니다 . 새로운 기본 이미지가 없으면 iPhone 5는 일반적인 480×320 화면 크기 (포인트)를보고합니다. 따라서 확인은 와이드 스크린 가용성뿐만 아니라 와이드 스크린 모드도 활성화 됩니다.

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


답변

다음은 우리의 코드 입니다 .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 )


답변

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)