ios [UIScreen mainScreen].bounds.size 在 iOS8 中变得依赖于方向吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24150359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is [UIScreen mainScreen].bounds.size becoming orientation-dependent in iOS8?
提问by lwxted
I ran the following code in both iOS 7 and iOS 8:
我在 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);
The following is the result from iOS 8:
以下是来自 iOS 8 的结果:
Currently landscape: No, width: 320.00, height: 568.00
Currently landscape: Yes, width: 568.00, height: 320.00
Comparing to the result in iOS 7:
与 iOS 7 中的结果相比:
Currently landscape: No, width: 320.00, height: 568.00
Currently landscape: Yes, width: 320.00, height: 568.00
Is there any documentation specifying this change? Or is it a temporary bug in iOS 8 APIs?
是否有任何文档指定此更改?或者它是 iOS 8 API 中的一个临时错误?
采纳答案by vhristoskov
Yes, it's orientation-dependent in iOS8, not a bug. You could review session 214 from WWDC 2014 for more info: "View Controller Advancements in iOS 8"
是的,它在 iOS8 中依赖于方向,而不是错误。您可以查看 WWDC 2014 中的 session 214 以获取更多信息:“View Controller Advancements in iOS 8”
Quote from the presentation:
引自演讲:
UIScreen is now interface oriented:
UIScreen 现在是面向界面的:
- [UIScreen bounds] now interface-oriented
- [UIScreen applicationFrame] now interface-oriented
- Status bar frame notifications are interface-oriented
- Keyboard frame notifications are interface-oriented
- [UIScreen bounds] 现在面向界面
- [UIScreen applicationFrame] 现在面向界面
- 状态栏框架通知是面向界面的
- 键盘框架通知是面向界面的
回答by cbartel
Yes, it's orientation-dependent in iOS8.
是的,它在 iOS8 中依赖于方向。
I wrote a Util method to resolve this issue for apps that need to support older versions of the OS.
我编写了一个 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;
}
回答by MaxK
Yes, indeed, screen size is now orientation dependent in iOS 8. Sometimes, however, it's desired to get a size fixed to portrait orientation. Here is how I do it.
是的,确实,屏幕尺寸现在在 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;
}
回答by mnemia
Yes, it's now dependent on orientation.
是的,它现在取决于方向。
I prefer the below method of getting the screen size in an orientation-independent way to some of the answers above, both because it's simpler and because it doesn't depend on any of the orientation code (the state of which can be dependent on the time that they are called) or on version checking. You may want the new iOS 8 behavior, but this will work if you need it to be stable on all versions of iOS.
我更喜欢下面的以与方向无关的方式获取屏幕大小的方法,而不是上面的一些答案,既因为它更简单,又因为它不依赖于任何方向代码(其状态可以依赖于调用它们的时间)或版本检查。您可能需要新的 iOS 8 行为,但如果您需要它在所有版本的 iOS 上保持稳定,这将起作用。
+(CGSize)screenSizeOrientationIndependent {
CGSize screenSize = [UIScreen mainScreen].bounds.size;
return CGSizeMake(MIN(screenSize.width, screenSize.height), MAX(screenSize.width, screenSize.height));
}
回答by Antoine
Related to this question as it solved my problem, here two defines I use for screen width and height calculations:
与这个问题相关,因为它解决了我的问题,这里有两个定义我用于屏幕宽度和高度计算:
#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)
If you are supporting both iOS 7 and iOS 8, this is the best solution for this problem.
如果您同时支持 iOS 7 和 iOS 8,这是解决此问题的最佳解决方案。
回答by Leo Dabus
You can use nativeBounds
(orientation-independent)
您可以使用nativeBounds
(与方向无关)
nativeBounds
本地边界
The bounding rectangle of the physical screen, measured in pixels. (read-only)
Declaration SWIFT
var nativeBounds: CGRect { get }
This rectangle is based on the device in a portrait-up orientation. This value does not change as the device rotates.
物理屏幕的边界矩形,以像素为单位。(只读)
申报 SWIFT
var nativeBounds: CGRect { get }
此矩形基于纵向向上的设备。该值不会随着设备旋转而改变。
Detecting the device's height:
检测设备的高度:
if UIScreen.mainScreen().nativeBounds.height == 960.0 {
}
Detecting the device's width:
检测设备的宽度:
if UIScreen.mainScreen().nativeBounds.width == 640.0 {
}
回答by Julian Król
It is not a bug in iOS 8 SDK. They made bounds interface orientation depended.According to your question about some reference or documentation to that fact I will highly recommend you to watch View Controller Advancements in iOS 8
it is 214 session from WWDC 2014. The most interesting part (according to your doubts) is Screen Coordinates
which starts at 50:45.
这不是 iOS 8 SDK 中的错误。他们使边界界面方向取决于。根据您关于该事实的一些参考或文档的问题,我强烈建议您观看WWDC 2014 的View Controller Advancements in iOS 8
214 会议。最有趣的部分(根据你的疑惑)是从 50:45 开始的。Screen Coordinates
回答by hfossli
Yes, it's orientation-dependent in iOS8.
是的,它在 iOS8 中依赖于方向。
Here's how you can have a concistent way of reading out bounds in an iOS 8 fashion across SDK's and OS-versions.
下面介绍了如何以 iOS 8 方式在 SDK 和 OS 版本之间以一致的方式读取边界。
#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
回答by Uzair Khan
My solution is a combination of MaxK's and hfossli. I made this method on a Category of UIScreen and it has no version checks (which is a bad practice):
我的解决方案是结合 MaxK's 和 hfossli。我在 UIScreen 的 Category 上创建了这个方法,它没有版本检查(这是一个不好的做法):
//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;
}
回答by Joe Booth
I needed a quick helper function that kept the same behavior as iOS7 under iOS8 - this allowed me to swap out my [[UIScreen mainScreen] bounds]
calls and not touch other code...
我需要一个快速的帮助函数,它在 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;
}