在iOS 8之前,我们将以下代码与 supportedInterfaceOrientations 和 shouldAutoRotate 委托方法结合使用,以强制应用程序方向指向任何特定方向 . 我使用下面的代码段以编程方式将应用程序旋转到所需的方向 . 首先,我正在改变状态栏方向 . 然后只显示并立即关闭模态视图会将视图旋转到所需的方向 .
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
但这在iOS 8中失败了 . 而且,我已经看到堆栈溢出的一些答案,人们建议我们应该始终从iOS 8开始避免这种方法 .
更具体地说,我的应用程序是一种通用类型的应用程序 . 总共有三个控制器 .
-
First View controller - 它应支持iPad中的所有方向,并且仅支持iPhone中的纵向(主页按钮) .
-
Second View controller - 它应该只支持所有条件下的风景
-
Third View controller - 它应该只支持所有条件下的风景
我们使用导航控制器进行页面导航 . 从第一个视图控制器,在按钮单击操作上,我们在堆栈上推送第二个 . 因此,当第二个视图控制器到达时,无论设备方向如何,应用程序都应仅锁定横向 .
下面是我在第二个和第三个视图控制器中的 shouldAutorotate
和 supportedInterfaceOrientations
方法 .
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotate {
return NO;
}
对于这种或任何更好的方法来锁定iOS 8的特定方向的视图控制器是否有任何解决方案 . 请帮忙!!
24 回答
我在这里尝试了一些解决方案,重要的是要理解它是根视图控制器,它将确定它是否会旋转 .
我创建了以下 objective-c 项目github.com/GabLeRoux/RotationLockInTabbedViewChild,其中包含一个
TabbedViewController
的工作示例,其中一个子视图允许旋转,另一个子视图以纵向锁定 .它并不完美,但它有效,同样的想法应该适用于其他类型的根视图,例如
NavigationViewController
. :)根据@ sid-sha显示的解决方案,您必须将所有内容放在
viewDidAppear:
方法中,否则您将无法获取didRotateFromInterfaceOrientation:
,因此类似于:对于iOS 7 - 10:
Objective-C的:
斯威夫特3:
只需在显示的视图控制器的
- viewDidAppear:
中调用它 .如果你在
UINavigationController
或UITabBarController
内,方向旋转会更复杂一些 . 问题是如果视图控制器嵌入其中一个控制器中,导航或标签栏控制器优先,并决定自动旋转和支持的方向 .我在UINavigationController和UITabBarController上使用以下2个扩展,以便嵌入其中一个控制器的视图控制器可以做出决定 .
为视觉控制器提供动力!
Swift 2.3
Swift 3
现在您可以覆盖
supportedInterfaceOrientations
方法,或者可以在要锁定的视图控制器中覆盖shouldAutoRotate
,否则可以忽略其他视图控制器中要继承应用程序plist中指定的默认方向行为的覆盖禁用旋转
锁定特定方向
从理论上讲,这应该适用于所有复杂的视图控制器层次结构,但我注意到UITabBarController存在问题 . 出于某种原因,它想要使用默认方向值 . 如果您有兴趣了解如何解决某些问题,请参阅以下博文:
Lock Screen Rotation
这对我有用:
https://developer.apple.com/library//ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation
在viewDidAppear:方法中调用它 .
我发现如果它是一个呈现的视图控制器,你可以覆盖
preferredInterfaceOrientationForPresentation
迅速:
这种方式适合我在 Swift 2 iOS 8.x:
PS(这种方法不需要在每个viewController上覆盖定向函数,比如shouldautorotate,只需要AppDelegate上的一个方法)
检查项目常规信息中的"requires full screen" .
所以,在AppDelegate.swift上创建一个变量:
所以,还把这个功能:
因此,在项目的每个类中,您都可以在viewWillAppear中设置此var:
如果您需要根据设备类型进行选择,可以执行以下操作:
这应该从iOS 6开始向上,但我只在iOS 8上测试它 . 子类
UINavigationController
并覆盖以下方法:或询问可见的视图控制器
并在那里实施方法 .
这是对Sid Shah's answer中评论的反馈,关于如何使用以下方法禁用动画:
码:
首先 - 这是一个坏主意,一般来说,您的应用程序架构出现问题,但是,如果是这样,您可以尝试制作如下内容:
比,在
AppDelegate
每当你想改变方向时,请执行以下操作:
注意:有时,设备可能无法通过此类呼叫进行更新,因此您可能需要执行以下操作
就这样
在
Xcode 8
上,方法将转换为属性,因此以下方法适用Swift
:如果您使用的是navigationViewController,则应为此创建自己的超类并覆盖:
这将禁用 SecondViewController 中的旋转,但如果您在设备处于纵向方向时按 SecondViewController ,则 SecondViewController 将以纵向模式显示 .
假设您正在使用故事板 . 您必须在"onClick"方法中创建手动segue(How to):
这将在您的超类禁用自动旋转功能之前强制横向方向 .
我尝试了很多解决方案,但是工作的解决方案如下:
无需在ios 8和9中编辑
info.plist
.Possible orientations from the Apple Documentation:
Sids和Koreys答案的组合对我有用 .
扩展导航控制器:
然后在单个View上禁用旋转
并且在segue之前旋转到适当的方向
上面的顶级解决方案:
当我在所呈现的视图控制器的viewDidAppear中调用它时,我没有工作 . 但是,当我在呈现视图控制器中的preparForSegue中调用它时,它确实有效 .
(对不起,没有足够的声誉点评论该解决方案,所以我不得不像这样添加它)
我的要求是
以纵向模式锁定所有视图
使用
AVPlayerViewController
播放视频播放视频时,如果是风景,则允许屏幕向右旋转并向左旋转 . 如果是肖像,则仅以纵向模式锁定视图 .
首先,在
AppDelegate.swift
中定义supportedInterfaceOrientationsForWindow
其次,在主视图控制器中,定义以下功能
然后,你需要子类
AVPlayerViewController
在
MyPlayerViewController.swift
中覆盖这三个函数因为用户可能会向左或向右旋转设备横向,我们需要将自动旋转设置为true
最后,在视图控制器中创建
MyPlayerViewController
实例并设置属性大小值 .使用正确的
videoUrl
启动播放器,然后将播放器分配给playerViewController
. 快乐的编码![iOS9]如果有人一直拖到这里,因为以上解决方案都没有工作,如果你想要通过segue改变方向,你可能想检查一下 .
检查您的segue的演示文稿类型 . 我的是“当前的背景” . 当我将其更改为全屏时,它工作正常 .
感谢@GabLeRoux,我找到了这个解决方案 .
根据Korey Hinton's answer
Swift 2.2:
Disable Rotation
Lock to Specific Orientation
我的解决方案
在
AppDelegate
:XXViewController
是您要支持横向模式的ViewController .然后Sunny Shah's solution将适用于任何iOS版本的
XXViewController
:这是查找最顶层ViewController的实用程序函数 .
使用此方法锁定视图控制器方向,在IOS 9上测试:
//将方向锁定到横向右侧
关于如何最好地完成这项任务似乎还有一些争论,所以我想我会分享我的(工作)方法 . 在
UIViewController
实现中添加以下代码:对于此示例,您还需要在项目设置中(或直接在
info.plist
中)将允许的设备方向设置为'Landscape Left' . 如果您想要除LandscapeLeft.
之外的其他内容,只需更改您想要强制的特定方向对我而言,关键是
viewWillAppear
中的attemptRotationToDeviceOrientation
调用 - 如果没有物理旋转设备,视图将无法正确旋转 .我有同样的问题,浪费了很多时间 . 所以现在我有了解决方案 . 我的应用程序设置只是支持肖像 . 但是,我的应用程序中的某些屏幕只需要横向 . 我通过在 AppDelegate 处有一个变量 isShouldRotate 来修复它 . 而 AppDelegate 的功能:
最后当需要景观状态时 . 就这样做: before push/present 到 ViewControllerA 将 isShouldRotate 分配给 true . 不要忘记弹出/关闭控制器在 viewWillDisappear 时将 isShouldRotate 分配给 false .
对我来说,顶级VC需要实现方向覆盖 . 如果顶级VC未实现,则使用VC向下堆栈将不起作用 .
只听VC-Main,主要是在我的测试中 .