在我的通用应用程序中,我当前在窗口的根视图控制器中覆盖supportedInterfaceOrientations
以定义允许的方向。到目前为止,决定是基于设备的用户界面惯用语:
- (NSUInteger) supportedInterfaceOrientations
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
else
return UIInterfaceOrientationMaskAll;
}
现在我想改变它,以便我也可以支持iPhone 6 Plus的风景,但不支持其他iPhone。我可以想象一两个解决方案,但这些都非常脆弱,并且可能会在Apple开始制造新设备时破坏。
在理想的世界中,我想将上述方法更改为以下代码段,其中决策基于设备的用户界面大小类而不是用户界面成语:
- (NSUInteger) supportedInterfaceOrientations
{
// Note the hypothetical UIDevice method "landscapeSizeClass"
if ([[UIDevice currentDevice] landscapeSizeClass] == UIUserInterfaceSizeClassCompact)
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
else
return UIInterfaceOrientationMaskAll;
}
在UIKit的某个地方有类似神奇的landscapeSizeClass
方法吗?我在各种课程参考和指南中看了一下,但没有找到任何有用的东西。或者有人可以建议一个同样通用且面向未来的不同解决方案吗?
请注意,我的应用程序以编程方式创建其UI,因此纯粹基于故事板的解决方案已经完成。此外,我的应用程序仍然需要支持iOS 7,所以我不能只改变一切使用大小类。但是,我可以做的是在使用简单的iOS 8 API之前进行运行时检查。
答案 0 :(得分:2)
我宁愿使用宏来发现(出于可读性的原因),例如:
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#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_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)
然后:
- (NSUInteger) supportedInterfaceOrientations
{
if (IS_IPAD || IS_IPHONE_6P)
{
return UIInterfaceOrientationMaskAll;
}
else
{
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
}
编辑:
最好有一个宏而不是IS_IPHONE_6P和IS_IPAD:
#define IS_LANDSCAPE_REGULAR_SIZE (SCREEN_MAX_LENGTH >= 736.0)
然后:
if (IS_LANDSCAPE_REGULAR_SIZE) { ... }
答案 1 :(得分:1)
缺乏正式的Apple API,这是我提出的解决方法:
- (NSUInteger) supportedInterfaceOrientations
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
// iPhone 5S and below: 320x480
// iPhone 6: 375x667
// iPhone 6 Plus: 414x736
CGSize screenSize = [UIScreen mainScreen].bounds.size;
// The way how UIScreen reports its bounds has changed in iOS 8.
// Using MIN() and MAX() makes this code work for all iOS versions.
CGFloat smallerDimension = MIN(screenSize.width, screenSize.height);
CGFloat largerDimension = MAX(screenSize.width, screenSize.height);
if (smallerDimension >= 400 && largerDimension >= 700)
return UIInterfaceOrientationMaskAll;
else
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
else
{
// Don't need to examine screen dimensions on iPad
return UIInterfaceOrientationMaskAll;
}
}
该片段简单地假设尺寸高于半任意选择尺寸的屏幕适合旋转。 半 - 任意,因为400x700的门槛包括iPhone 6 Plus,但不包括iPhone 6。
虽然这个解决方案相当简单,但我完全喜欢,因为缺乏复杂性。我并不需要准确区分设备,所以任何聪明的解决方案(例如Jef's answer中的解决方案对我来说都是过度的。
答案 2 :(得分:0)
- (NSUInteger) supportedInterfaceOrientations {
if (self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular ||
self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) {
return UIInterfaceOrientationMaskAll;
} else {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
}
<强>更新强> 以前不工作所以这里有不同的解决方案
- (NSUInteger) supportedInterfaceOrientations {
if (self.traitCollection.displayScale == 3.0 || (self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular &&
self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular)) {
return UIInterfaceOrientationMaskAll;
} else {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
}
答案 3 :(得分:0)
Fwiw,相当于Swift 1.2中的herzbube's answer:
override func supportedInterfaceOrientations() -> Int {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
let size = self.view.bounds.size
let smallerDimension = min(size.width, size.height)
let largerDimension = max(size.width, size.height)
if smallerDimension >= 400 && largerDimension >= 700 {
return Int(UIInterfaceOrientationMask.All.rawValue)
} else {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
} else {
return Int(UIInterfaceOrientationMask.All.rawValue)
}
}
虽然我个人更喜欢以下风格:
override func supportedInterfaceOrientations() -> Int {
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
return Int(UIInterfaceOrientationMask.All.rawValue)
}
let size = self.view.bounds.size
let smallerDimension = min(size.width, size.height)
let largerDimension = max(size.width, size.height)
return smallerDimension >= 400 && largerDimension >= 700 ?
Int(UIInterfaceOrientationMask.All.rawValue) :
Int(UIInterfaceOrientationMask.Portrait.rawValue)
}