我想提供一个响应方向更改的视图但由于各种原因无法使用iOS的内置自动旋转。在viewDidLoad
中,我使用当前方向来确定视图的初始布局:
_originalOrientation = [UIDevice currentDevice].orientation;
// if we were launched flat or unknown, use the status bar orientation as a guide
if (_originalOrientation == UIDeviceOrientationUnknown ||
_originalOrientation == UIDeviceOrientationFaceDown ||
_originalOrientation == UIDeviceOrientationFaceUp) {
_originalOrientation = UIDeviceOrientationFromInterfaceOrientation([UIApplication sharedApplication].statusBarOrientation);
}
从我的评论中可以看出,我需要处理[UIDevice currentDevice].orientation
不是可用方向的情况(即设备是平的或未知的方向)。在这种情况下,我尝试使用statusBarOrientation
推断设备的方向(使用UIViewController
的{{1}}将是另一种获取相同信息的方式):
interfaceOrientation
但是我的逻辑无法准确辨别这两种情况,因为它们被UIDeviceOrientation UIDeviceOrientationFromInterfaceOrientation(UIInterfaceOrientation interface) {
// note: because UIInterfaceOrientationLandscapeLeft and UIInterfaceOrientationLandscapeRight have the same value, this conversion can't distinguish them
if (interface == UIInterfaceOrientationLandscapeLeft) {
return UIDeviceOrientationLandscapeLeft;
} else if (interface == UIInterfaceOrientationLandscapeRight) {
return UIDeviceOrientationLandscapeRight;
} else if (interface == UIInterfaceOrientationPortraitUpsideDown) {
return UIDeviceOrientationPortraitUpsideDown;
} else {
return UIDeviceOrientationPortrait;
}
}
定义为相同的常量值:
UIApplication.h
我是否可以通过其他方式区分// Note that UIInterfaceOrientationLandscapeLeft is equal to UIDeviceOrientationLandscapeRight (and vice versa).
// This is because rotating the device to the left requires rotating the content to the right.
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
};
和UIInterfaceOrientationLandscapeLeft
?除了使用状态栏方向之外,还有更好的方法来执行我的“后备”逻辑吗?
答案 0 :(得分:3)
UIDevice的orientation属性是一个enum,可以区分左右横向(它们的值分别为3和4),因此您可以检查该值。
typedef enum {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,
UIDeviceOrientationPortraitUpsideDown,
UIDeviceOrientationLandscapeLeft,
UIDeviceOrientationLandscapeRight,
UIDeviceOrientationFaceUp,
UIDeviceOrientationFaceDown
} UIDeviceOrientation;
答案 1 :(得分:3)
您写道:
然而,我的逻辑无法准确地辨别出两个景观案例 因为它们被定义为UIApplication.h是相同的常量值
我很确定他们不是!接口和设备方向的值交换。见UIApplication.h
:
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
};
界面方向 UIInterfaceOrientationLandscapeLeft
等于设备方向 UIDeviceOrientationLandscapeRight
,反之亦然。但是:
UIInterfaceOrientationLandscapeLeft != UIInterfaceOrientationLandscapeRight
UIDeviceOrientationLandscapeLeft != UIDeviceOrientationLandscapeRight
试试这段代码,我认为这样可以解决问题:
UIDeviceOrientation UIDeviceOrientationFromInterfaceOrientation(UIInterfaceOrientation interface) {
// interface orientation left is device orientation right
if (interface == UIInterfaceOrientationLandscapeLeft) {
return UIDeviceOrientationLandscapeRight;
// interface orientation right is device orientation left
} else if (interface == UIInterfaceOrientationLandscapeRight) {
return UIDeviceOrientationLandscapeLeft;
} else if (interface == UIInterfaceOrientationPortraitUpsideDown) {
return UIDeviceOrientationPortraitUpsideDown;
} else {
return UIDeviceOrientationPortrait;
}
}
顺便说一下,您还应考虑为您的函数使用自己的前缀而不是UI
,否则可能很容易错误地认为UIDeviceOrientationFromInterfaceOrientation
是API函数。
答案 2 :(得分:0)
如果您正在显示相机所看到的内容,我会忽略所有方向,并向用户显示设备在纵向中看到的内容。他们所看到的将永远是“正确的”,并且永远不会意外颠倒。
答案 3 :(得分:0)
您始终可以使用gravity
类的CMDeviceMotion
属性来确定设备方向。属性返回指向地球中心的标准化向量(也称为真实重力向量)。如果你对角度不感兴趣,你可以只测试符号并为你的目的生成常数。
答案 4 :(得分:0)
这是我在传递中的方式
创建一个名为previousOr的全局变量。然后在您的第一个viewController中使用以下代码来确定状态栏位置。我把它放在viewDidAppear
中if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) {
previousOr = [NSString stringWithFormat:@"L"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) {
previousOr = [NSString stringWithFormat:@"L"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
previousOr = [NSString stringWithFormat:@"P"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) {
previousOr = [NSString stringWithFormat:@"P"];
}
然后在您的后续viewControllers中,您在ViewDidLoad方法中有以下内容,这将检测设备是纵向还是横向,或者设备是否平坦,设备在放平之前所处的位置:
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
NSLog(@"landscape");
[self switchToLandscape];
}
else if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)) {
NSLog(@"portrait");
[self switchToPortrait];
}
else {
if ([previousOr isEqualToString:@"L"]) {
[self switchToLandscape];
}
else {
[self switchToPortrait];
}
}
然后你还有以下内容来重新绘制视图中的元素
- (void)switchToLandscape {
previousOr = [NSString stringWithFormat:@"L"];
//do stuff like replot centers
}
- (void)switchToPortrait {
previousOr = [NSString stringWithFormat:@"P"];
//do stuff like replot centers
}
然后您还可以检测方向的变化:
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) {
[self switchToLandscape];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) {
[self switchToLandscape];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
[self switchToPortrait];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) {
[self switchToPortrait];
}
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(BOOL) shouldAutorotate {
return YES;
}
请注意;为了向后兼容,我输入了shouldAutorotateToInterfaceOrientation和shouldAutoRotate。
答案 5 :(得分:0)
遇到了同样的问题。这就是答案,请始终使用UIIntefaceOrientation来检查当前方向是横向还是纵向。
目标C:
if([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeRight)
{
//Go Here for landscape
}
else if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown)
{
//Go Here for Portrait
}
SWIFT:
let currentOrient : UIInterfaceOrientation = UIApplication.shared.statusBarOrientation
if currentOrient == UIInterfaceOrientation.landscapeLeft || currentOrient == UIInterfaceOrientation.landscapeRight
{
//Go Here for landscape
}
else if currentOrient == UIInterfaceOrientation.portrait || currentOrient == UIInterfaceOrientation.portraitUpsideDown
{
//Go Here for Portrait
}