我想要一些我的ViewControllers景观和一些肖像,所以这就是我所做的:
我启用了横向模式:
接下来,我将这些代码行添加到我想成为肖像的视图控制器中:
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
-(BOOL)shouldAutorotate
{
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
然而,当我旋转它们时,它们仍然会进入横向模式。我如何解决这个问题?
答案 0 :(得分:21)
Apple为UINavigationController
设计的方法是通过UINavigationControllerDelegate
。
通常我只是更新此委托以执行以下操作并将其委托给导航控制器堆栈中的顶部显示控制器:
#pragma mark - UINavigationControllerDelegate
- (NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController
{
return [navigationController.topViewController supportedInterfaceOrientations];
}
在我看来,UINavigationController
应该默认为上述行为,但这是Apple提供的API:)
至于信息plist文件,我取消选中所有选项并在代码中处理所有选项,因为它在过去给我带来了问题,而我厌倦了处理它。
答案 1 :(得分:15)
我是这样做的。
创建一个UINavigationController父类。
在你内部UINavigationController(父)覆盖这些方法,如:
- (NSUInteger)supportedInterfaceOrientations
{
if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientationsForThisContorller)])
{
return(NSInteger)[self.topViewController performSelector:@selector(supportedInterfaceOrientationsForThisContorller) withObject:nil];
}
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
if([self.visibleViewController respondsToSelector:@selector(shouldAutorotateNow)])
{
BOOL autoRotate = (BOOL)[self.visibleViewController
performSelector:@selector(shouldAutorotateNow)
withObject:nil];
return autoRotate;
}
return NO;
}
现在您的NavigationController应该是UINavigationContorller父
的子类斯威夫特3:
在UINavigationController子类中执行此操作
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
get {
return self.topViewController?.supportedInterfaceOrientations ?? .all
}
}
override var shouldAutorotate: Bool {
return self.topViewController?.shouldAutorotate ?? false
}
<强>更新强> 如果您不想继承,可以从Matt的answer获取:
首先:使viewController成为viewDidLoad
self.navigationController?.delegate = self
然后声明UIViewController扩展以响应委托方法,如下所示:
extension UIViewController: UINavigationControllerDelegate {
public func navigationControllerSupportedInterfaceOrientations(_ navigationController: UINavigationController) -> UIInterfaceOrientationMask {
return navigationController.topViewController?.supportedInterfaceOrientations
}
}
答案 2 :(得分:3)
Just for you all information, create a new project single view based Application, implement the should auto rotate delegate and the supportedInterface orientation in viewController add breakpoint in it.
The run (universal mode)
So don't waste too mush time on it like I juste Did, XCode 7.3 is BUGGED
答案 3 :(得分:0)
答案 4 :(得分:0)
在UINavigationController下,我正在实现UINavigationControllerDelegate和以下方法:
#pragma mark - From UINavigationControllerDelegate
-(UIInterfaceOrientationMask) navigationControllerSupportedInterfaceOrientations:(UINavigationController*)navigationController {
return UIInterfaceOrientationMaskPortrait; // TODO: change to whatever you need to allow
}
答案 5 :(得分:0)
为简单起见,对于iPad,如果info.plist中的支持的界面方向(iPad)属性包括所有四个方向,并且 UIRequiresFullScreen 属性值为 NO ,iOS会将您的应用视为支持拆分视图。如果某个应用程序支持拆分视图功能,则至少通过上述方式,您不能禁止其旋转。
让我们深入研究细节。
首先,我们需要知道哪些因素会影响屏幕方向:
1。项目设置(info.plist)
我们可以在两个地方进行此设置:
这两种方法相同,一个将自动同步另一个设置。 在info.plist文件中,支持的界面方向(iPad)属性用于iPad设置(为 Device 部分选择 iPad )和支持的界面方向属性适用于iPhone和Univeral(对于 Device 部分,选择 iPhone 或 Universal 部分,这两个设置将始终为一样。)
2。以编程方式设置支持的屏幕方向
有两种方法可以在编码时配置支持的方向:
supportedInterfaceOrientationsForWindow:
中的UIApplicationDelegate
方法supportedInterfaceOrientations
中的UIViewController
方法iOS系统将检查两种方法中定义的通用方向,并将这些通用方向用作视图控制器的支持方向。
3。在shouldAutorotate
UIViewController
属性
这是一个只读属性,用于控制视图控制器是否可旋转。您可以在视图控制器中覆盖该属性,甚至可以将该属性更改为可读写属性,以便您可以在应用运行时修改该属性。例如:
override public var shouldAutorotate: Bool {
get {
return self.shouldAutorotateVariable
}
set {
self.shouldAutorotateVariable = newValue
}
}
shouldAutorotateVariable
是视图控制器中的私有属性。
如果视图控制器的shouldAutorotate
属性设置为false
,iOS将忽略以下设置:
supportedInterfaceOrientationsForWindow:
中的UIApplicationDelegate
方法supportedInterfaceOrientations
中的UIViewController
方法iOS将仅使用项目设置(info.plist)。
如果未覆盖shouldAutorotate
属性或将其设置为true
,则iOS将使用以下两种方法定义的通用方向:
supportedInterfaceOrientationsForWindow:
中的UIApplicationDelegate
方法supportedInterfaceOrientations
中的UIViewController
方法如果未提供上述两种方法,iOS将使用项目设置(info.plist)。
iPad从iOS9开始支持拆分视图功能。有关分割视图的设置,请参见Slide Over and Split View Quick Start。
为简单起见,如果info.plist中的支持的界面方向(iPad)属性包括所有四个方向,且 UIRequiresFullScreen 属性值为 NO ,iOS会将您的应用视为支持拆分视图。如果该应用支持拆分视图,则以下两个设置将被省略:
supportedInterfaceOrientationsForWindow:
中的UIApplicationDelegate
方法supportedInterfaceOrientations
中的UIViewController
方法 shouldAutorotate
中的UIViewController
属性也将被忽略。
也就是说,如果应用程序支持拆分视图功能,则至少通过上述方式,您不能禁止其旋转。
如果info.plist值中的支持的界面方向(iPad)属性未包含所有四个方向,或者 UIRequiresFullScreen 属性设置为 YES ,该应用将不支持拆分视图,并且屏幕方向控制逻辑与上述iPhone相同。
注意:对于项目设置(info.plist),最好直接在info.plist内设置以下三个属性:
- 支持的界面方向(iPad)
- 支持的界面方向
- UIRequiresFullScreen
如果您尝试通过 Project-> Target-> General-> Device Orientation 进行设置,则会造成混淆:即使 Device 都设置为 Universe , iPad 中的设置仍将生效。
答案 6 :(得分:0)
如果上述解决方案不起作用,那么如果您使用的是UITabBarController
,则需要继承UITabBarController
的子类,并需要重写以下方法
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
我建议您对.all
使用iPad
扩展
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIDevice.current.userInterfaceIdiom == .phone ? [.portrait, .portraitUpsideDown] : .all
}
希望对遇到相同问题的人有所帮助