방금 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 이하를 대상으로하는 경우 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를 감지해야하는 경우 해당 화면 크기를 사용하십시오.
답변
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)