我刚刚升级到Xcode 4.5 GM,发现你现在可以将“4英寸视网膜”大小应用到故事板中的视图控制器上。
现在,如果我想创建一个同时在iPhone 4和5上运行的应用程序,当然我必须构建每个窗口两次,但我还必须检测用户的iPhone屏幕是3.5英寸还是4英寸,然后应用视图。
我该怎么做呢?
我刚刚升级到Xcode 4.5 GM,发现你现在可以将“4英寸视网膜”大小应用到故事板中的视图控制器上。
现在,如果我想创建一个同时在iPhone 4和5上运行的应用程序,当然我必须构建每个窗口两次,但我还必须检测用户的iPhone屏幕是3.5英寸还是4英寸,然后应用视图。
我该怎么做呢?
当前回答
我认为它应该很好,如果这个宏将在设备和模拟器中工作,下面是解决方案。
#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)
其他回答
针对SDK和OS的任何组合进行测试和设计:
斯威夫特
增加了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的maxLength为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是本例中的理想结果。
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处于放大模式,UI就是放大版的iPhone 5。这些功能不是决定设备类型,而是决定显示模式,因此iPhone 5是本例中的理想结果。
这是我的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))
借用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
}
}
在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
}
因此,代码清楚地表明这是对主屏幕的检查,而不是对设备模型的检查。
通过这种方式,您可以检测设备系列。
#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