Q& A - 如何强制设备方向在横向和纵向之间旋转

时间:2018-03-14 03:52:27

标签: ios objective-c orientation

  

我在Q&A style发帖,因为目前有一些帖子    S / O,类似的问题和答案不完全正确   适用于所有用例。它们通常足以满足OP的一个特定用例   但对于访问网站搜索常规用户的人来说却不好   回答并导致数小时的沮丧调试,因为我只是   经历。 (并且通过所有StackOverflow的进行抨击   资源发现此问题(及其答案)尚未   除了对其他帖子的评论外,正式询问任何地方。

问:如何强制我的应用随意切换纵向和横向模式?

虽然有许多微小的片段允许它,但它们以各种不可预知的方式失败。

例如:

1)您可以旋转屏幕UI(而不是设备方向),但如果您截图或显示iOS本机内容,例如弹出警报,则会以错误的方式定向。

2)如果您将orientation键设置为所需的方向,则UI(或根本不会)会立即自动更新。

3)如果您只是手动执行此操作并手动更新UI,则其他VC可能仍会篡改w /方向,而不是“锁定”。

4)如果您手动更新设备方向并刷新UI,添加新的ViewController.view将会翻转宽度和高度,因为即使UI有设备设置尚未更新,您还必须等待未知数量的旋转动画在更新这些属性(UIDevice的尺寸)之前完成的时间(介于0和1秒之间)。

我的回答解决了搜索各种SO线程时发现的所有潜在问题。

1 个答案:

答案 0 :(得分:1)

A:

添加到AppDelegate.h

@property () BOOL landscape;

添加到AppDelegate.m

-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if (self.landscape) {
        return UIInterfaceOrientationMaskLandscapeRight;
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}


-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    if (self.landscape) {
        return UIInterfaceOrientationLandscapeRight;
    } else {
        return UIInterfaceOrientationPortrait;
    }
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    if (self.landscape) {
        return (UIInterfaceOrientationLandscapeRight);
    } else {
        return (UIInterfaceOrientationPortrait);
    }
}

-(NSUInteger)supportedInterfaceOrientations {
    if (self.landscape) {
        return UIInterfaceOrientationLandscapeRight;
    } else {
        return UIInterfaceOrientationPortrait;
    }
}

-(BOOL)shouldAutorotate {
    return NO;
}

添加到VC.m

-(void)setLandscape:(BOOL)landscape {

    AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    appDelegate.landscape = landscape;

    if (landscape) {
        NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    } else {
        NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }

    [UINavigationController attemptRotationToDeviceOrientation];//THIS IS THE MOST IMPORTANT LINE IN HERE AND EVERYONE AND ALL SAMPLE CODE LEAVES IT OUT FOR SOME REASON, DO NOT REMOVE THIS LINE. (Forces UI to update), otherwise this orientation change will randomly fail around 1% of the time as UI doesn't refresh for various unknown reasons.

}

最重要的一行是[UINavigationController attemptRotationToDeviceOrientation];,由于某些原因,网络上的所有人,堆栈溢出,示例代码等都会遗漏。只需设置orientation键就可以使98%的时间工作,但是随机UI不会更新,或者在设置密钥之前它会更新并且你会得到一个方向错误,这会强制它在你需要时更新它来。