我在iOS 7和iOS 8中都运行了以下代码:
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
BOOL landscape = (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight);
NSLog(@"Currently landscape: %@, width: %.2f, height: %.2f",
(landscape ? @"Yes" : @"No"),
[[UIScreen mainScreen] bounds].size.width,
[[UIScreen mainScreen] bounds].size.height);
以下是iOS 8的结果:
Currently landscape: No, width: 320.00, height: 568.00
Currently landscape: Yes, width: 568.00, height: 320.00
与iOS 7中的结果相比:
Currently landscape: No, width: 320.00, height: 568.00
Currently landscape: Yes, width: 320.00, height: 568.00
是否有任何文件指明此更改?或者它是iOS 8 API中的临时错误?
答案 0 :(得分:173)
是的,它在iOS8中取决于方向,而不是bug。您可以查看WWDC 2014的会话214以获取更多信息:"View Controller Advancements in iOS 8"
来自演示文稿的引用:
UIScreen现在面向接口:
答案 1 :(得分:59)
是的,它在iOS8中取决于方向。
我编写了一个Util方法来为需要支持旧版操作系统的应用程序解决此问题。
+ (CGSize)screenSize {
CGSize screenSize = [UIScreen mainScreen].bounds.size;
if ((NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
return CGSizeMake(screenSize.height, screenSize.width);
}
return screenSize;
}
答案 2 :(得分:34)
是的,确实,屏幕尺寸现在取决于iOS 8。但是,有时需要将尺寸固定为纵向。我就是这样做的。
+ (CGRect)screenBoundsFixedToPortraitOrientation {
UIScreen *screen = [UIScreen mainScreen];
if ([screen respondsToSelector:@selector(fixedCoordinateSpace)]) {
return [screen.coordinateSpace convertRect:screen.bounds toCoordinateSpace:screen.fixedCoordinateSpace];
}
return screen.bounds;
}
答案 3 :(得分:32)
是的,它现在取决于方向。
我更喜欢以下方法,以与上述某些答案无关的方式获取屏幕尺寸,因为它更简单,并且因为它不依赖于任何方向代码(其状态可以取决于它们被调用的时间)或版本检查。您可能需要新的iOS 8行为,但如果您需要它在所有版本的iOS上保持稳定,这将会有效。
+(CGSize)screenSizeOrientationIndependent {
CGSize screenSize = [UIScreen mainScreen].bounds.size;
return CGSizeMake(MIN(screenSize.width, screenSize.height), MAX(screenSize.width, screenSize.height));
}
答案 4 :(得分:11)
与此问题相关,因为它解决了我的问题,这里有两个用于屏幕宽度和高度计算的定义:
#define SCREEN_WIDTH (IOS_VERSION_LOWER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height) : [[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT (IOS_VERSION_LOWER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width) : [[UIScreen mainScreen] bounds].size.height)
#define IOS_VERSION_LOWER_THAN_8 (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
如果您同时支持iOS 7和iOS 8,这是此问题的最佳解决方案。
答案 5 :(得分:9)
您可以使用nativeBounds
(与方向无关)
<强> nativeBounds 强>
物理屏幕的边界矩形,以像素为单位。 (只读)
宣言SWIFT
var nativeBounds: CGRect { get }
此矩形基于纵向方向的设备。这个 设备旋转时,值不会改变。
检测设备的高度:
if UIScreen.mainScreen().nativeBounds.height == 960.0 {
}
检测设备的宽度:
if UIScreen.mainScreen().nativeBounds.width == 640.0 {
}
答案 6 :(得分:8)
这不是iOS 8 SDK中的错误。 他们依赖于界面方向。根据您对该事实的一些参考或文档的问题,我强烈建议您从WWDC 2014观看View Controller Advancements in iOS 8
它是214会话。最有趣的部分(根据你的怀疑)是Screen Coordinates
,从50:45开始。
答案 7 :(得分:5)
是的,它在iOS8中取决于方向。
以下是如何通过SDK和OS版本以iOS 8方式读取边界的一致方式。
#ifndef NSFoundationVersionNumber_iOS_7_1
# define NSFoundationVersionNumber_iOS_7_1 1047.25
#endif
@implementation UIScreen (Legacy)
// iOS 8 way of returning bounds for all SDK's and OS-versions
- (CGRect)boundsRotatedWithStatusBar
{
static BOOL isNotRotatedBySystem;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
BOOL OSIsBelowIOS8 = [[[UIDevice currentDevice] systemVersion] floatValue] < 8.0;
BOOL SDKIsBelowIOS8 = floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1;
isNotRotatedBySystem = OSIsBelowIOS8 || SDKIsBelowIOS8;
});
BOOL needsToRotate = isNotRotatedBySystem && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
if(needsToRotate)
{
CGRect screenBounds = [self bounds];
CGRect bounds = screenBounds;
bounds.size.width = screenBounds.size.height;
bounds.size.height = screenBounds.size.width;
return bounds;
}
else
{
return [self bounds];
}
}
@end
答案 8 :(得分:4)
我的解决方案是MaxK&hsossli的组合。我在UIScreen类别上制作了这个方法,它没有版本检查(这是一种不好的做法):
//Always return the iOS8 way - i.e. height is the real orientation dependent height
+ (CGRect)screenBoundsOrientationDependent {
UIScreen *screen = [UIScreen mainScreen];
CGRect screenRect;
if (![screen respondsToSelector:@selector(fixedCoordinateSpace)] && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
screenRect = CGRectMake(screen.bounds.origin.x, screen.bounds.origin.y, screen.bounds.size.height, screen.bounds.size.width);
} else {
screenRect = screen.bounds;
}
return screenRect;
}
答案 9 :(得分:3)
我需要一个快速帮助函数,它在iOS8下保持与iOS7相同的行为 - 这使我可以换掉[[UIScreen mainScreen] bounds]
个调用而不触及其他代码......
+ (CGRect)iOS7StyleScreenBounds {
CGRect bounds = [UIScreen mainScreen].bounds;
if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
return bounds;
}
答案 10 :(得分:3)
以下方法可用于查找给定方向的屏幕边界,与iOS版本无关。此方法将根据设备的屏幕大小返回边界,并将提供与iOS版本无关的相同CGRect值。
- (CGRect)boundsForOrientation:(UIInterfaceOrientation)orientation {
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
CGFloat height = [[UIScreen mainScreen] bounds].size.height;
CGRect bounds = CGRectZero;
if (UIInterfaceOrientationIsLandscape(orientation)) {
bounds.size = CGSizeMake(MAX(width, height), MIN(width, height));
} else {
bounds.size = CGSizeMake(MIN(width, height), MAX(width, height));
}
return bounds;
}
// For the below example, bounds will have the same value if you run the code on iOS 8.x or below versions.
CGRect bounds = [self boundsForOrientation:UIInterfaceOrientationPortrait];
答案 11 :(得分:1)
这就是我用来计算正确矩形的东西:
UIScreen* const mainScreen = [UIScreen mainScreen];
CGRect rect = [mainScreen bounds];
#ifdef __IPHONE_8_0
if ([mainScreen respondsToSelector:@selector(coordinateSpace)])
{
if ([mainScreen respondsToSelector:@selector(fixedCoordinateSpace)])
{
id tmpCoordSpace = [mainScreen coordinateSpace];
id tmpFixedCoordSpace = [mainScreen fixedCoordinateSpace];
if ([tmpCoordSpace respondsToSelector:@selector(convertRect:toCoordinateSpace:)])
{
rect = [tmpCoordSpace convertRect:rect toCoordinateSpace: tmpFixedCoordSpace];
}
}
}
#endif
答案 12 :(得分:1)
只需添加上面回答的优秀cbartel功能的快速版本。
func screenSize() -> CGSize {
let screenSize = UIScreen.mainScreen().bounds.size
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) && UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) {
return CGSizeMake(screenSize.height, screenSize.width)
}
return screenSize
}
答案 13 :(得分:1)
我的问题与UIWindows框架有关,该框架在减去。 所以在MyViewController中制作了如下代码 - (NSUInteger)supportedInterfaceOrientations方法
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[self.view setFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
[appDel.window setFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
它为我的工作尝试。
答案 14 :(得分:0)
我注意到的一件事是,Info.plist中受支持的界面方向的顺序很重要。我的应用程序遇到了这个问题的问题(代码中的方向),但我没有指定默认方向为Portrait的任何地方。
我认为默认方向在任何情况下都是人像。
在Info.plist中重新排列itens,将Portrait放在第一位,恢复了预期的行为。
答案 15 :(得分:0)
使用稍微修改过的mnemia的解决方案,没有iOS版本检查的解决方案,在主屏幕范围内使用min / max。
我需要一个CGRect
,因此从主屏幕边界获得了CGRect
并更改了size.width=min(w,h)
,size.height=max(w,h)
。然后我在我的代码中的两个地方调用了独立于操作系统的get CGRect
函数,在那里我获得了OpenGL
的屏幕大小,触摸等。在修复之前我有2个问题 - 在IOS 8.x中的横向OpenGL
视图的模式显示位置不正确:左下角全屏的1/4。第二次触摸返回无效值。如所解释的那样,这两个问谢谢!
答案 16 :(得分:0)
这将在 iOS7 和 iOS8 中提供正确的设备,
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define IS_PORTRAIT UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)
+ (BOOL)isIPHONE4{
// < iOS 8.0
if(SYSTEM_VERSION_LESS_THAN(@"8.0")){
if ([self getDeviceWidth] == 320.0 && [self getDeviceHeight] == 480.0) {
return YES;
} else {
return NO;
}
// >= iOS 8.0
}else{
if(IS_PORTRAIT){
if ([self getDeviceWidth] == 320.0 && [self getDeviceHeight] == 480.0) {
return YES;
} else {
return NO;
}
}else{
if ([self getDeviceWidth] == 480.0 && [self getDeviceHeight] == 320.0) {
return YES;
} else {
return NO;
}
}
}
}
+ (BOOL)isIPHONE5{
// < iOS 8.0
if(SYSTEM_VERSION_LESS_THAN(@"8.0")){
if ([self getDeviceWidth] == 320.0 && [self getDeviceHeight] == 568.0) {
return YES;
} else {
return NO;
}
// >= iOS 8.0
}else{
if(IS_PORTRAIT){
if ([self getDeviceWidth] == 320.0 && [self getDeviceHeight] == 568.0) {
return YES;
} else {
return NO;
}
}else{
if ([self getDeviceWidth] == 568.0 && [self getDeviceHeight] == 320.0) {
return YES;
} else {
return NO;
}
}
}
}
+ (BOOL)isIPHONE6{
// < iOS 8.0
if(SYSTEM_VERSION_LESS_THAN(@"8.0")){
if ([self getDeviceWidth] == 375.0 && [self getDeviceHeight] == 667.0) {
return YES;
} else {
return NO;
}
// >= iOS 8.0
}else{
if(IS_PORTRAIT){
if ([self getDeviceWidth] == 375.0 && [self getDeviceHeight] == 667.0) {
return YES;
} else {
return NO;
}
}else{
if ([self getDeviceWidth] == 667.0 && [self getDeviceHeight] == 375.0) {
return YES;
} else {
return NO;
}
}
}
}
+ (BOOL)isIPHONE6Plus{
// < iOS 8.0
if(SYSTEM_VERSION_LESS_THAN(@"8.0")){
if ([self getDeviceWidth] == 414.0 && [self getDeviceHeight] == 736.0) {
return YES;
} else {
return NO;
}
// >= iOS 8.0
}else{
if(IS_PORTRAIT){
if ([self getDeviceWidth] == 414.0 && [self getDeviceHeight] == 736.0) {
return YES;
} else {
return NO;
}
}else{
if ([self getDeviceWidth] == 736.0 && [self getDeviceHeight] == 414.0) {
return YES;
} else {
return NO;
}
}
}
}
+ (CGFloat)getDeviceHeight{
//NSLog(@"Device width: %f",[UIScreen mainScreen].bounds.size.height);
return [UIScreen mainScreen].bounds.size.height;
}
+ (CGFloat)getDeviceWidth{
//NSLog(@"Device width: %f",[UIScreen mainScreen].bounds.size.height);
return [UIScreen mainScreen].bounds.size.width;
}
//您也可以添加更多设备(ieiPad)。
答案 17 :(得分:0)
iOS 8或更高版本
对于想要找出屏幕尺寸(3.5英寸屏幕有320×480点,4.0英寸屏幕有320×568点等)的人的解决方案将是
- (CGSize)screenSizeInPoints
{
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
CGFloat height = [[UIScreen mainScreen] bounds].size.height;
if (width > height) {
return CGSizeMake(height, width);
}
else {
return [[UIScreen mainScreen] bounds].size;
}
}