ios 如何使用swift仅锁定主视图的纵向
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25606442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to lock portrait orientation for only main view using swift
提问by Mono.WTF
I have created an application for iPhone, using swift, that is composed from many views embedded in a navigation controller. I would like to lock the main view to Portrait orientation and only a subview of a navigation controller locked in Landscape orientation. Here is an example of what i mean:
我使用swift为 iPhone 创建了一个应用程序,它由嵌入在导航控制器中的许多视图组成。我想将主视图锁定为纵向,并且仅将导航控制器的子视图锁定为横向。这是我的意思的一个例子:
- UINavigationController
- UiViewController1 (Locked in Portrait) Initial view controller with a button placed on the navigation bar that give to the user the possibility to access to a lists where can be selected other views
- UIViewController2 (Locked in Landscape)
- UiViewController3 (Portrait and Landscape)
- UiViewController4 (Portrait and Landscape)
- ...
- ...
- 导航控制器
- UiViewController1 (Locked in Portrait)初始视图控制器,导航栏上有一个按钮,让用户可以访问可以选择其他视图的列表
- UIViewController2(横向锁定)
- UiViewController3(纵向和横向)
- UiViewController4(纵向和横向)
- ...
- ...
How Can i do that?
我怎样才能做到这一点?
回答by JasonJasonJason
According to the Swift Apple Docsfor supportedInterfaceOrientations
:
根据Swift Apple Docsfor supportedInterfaceOrientations
:
Discussion
When the user changes the device orientation, the system calls this method on the root view controller or the topmost presented view controller that fills the window. If the view controller supports the new orientation, the window and view controller are rotated to the new orientation. This method is only called if the view controller's shouldAutorotate method returns true.
讨论
当用户更改设备方向时,系统会在根视图控制器或填充窗口的最上面呈现的视图控制器上调用此方法。如果视图控制器支持新方向,则窗口和视图控制器将旋转到新方向。仅当视图控制器的 shouldAutorotate 方法返回 true 时才会调用此方法。
Your navigation controller should override shouldAutorotate
and supportedInterfaceOrientations
as shown below. I did this in a UINavigationController
extension for ease:
您的导航控制器应该覆盖shouldAutorotate
和supportedInterfaceOrientations
如下所示。UINavigationController
为了方便起见,我在扩展中做到了这一点:
extension UINavigationController {
public override func shouldAutorotate() -> Bool {
return true
}
public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return (visibleViewController?.supportedInterfaceOrientations())!
}
}
And your main viewcontroller (portrait at all times), should have:
您的主视图控制器(始终为纵向)应该具有:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
Then, in your subviewcontrollers that you want to support portrait or landscape:
然后,在您想要支持纵向或横向的子视图控制器中:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.All
}
Edit: Updated for iOS 9 :-)
编辑:为 iOS 9 更新:-)
回答by bmjohns
Also answered [here]
也回答了[这里]
Things can get quite messy when you have a complicated view hierarchy, like having multiple navigation controllers and/or tab view controllers.
当你有一个复杂的视图层次结构时,事情会变得非常混乱,比如有多个导航控制器和/或选项卡视图控制器。
This implementation puts it on the individual view controllers to set when they would like to lock orientations, instead of relying on the App Delegate to find them by iterating through subviews or relying on inheritance.
这个实现把它放在各个视图控制器上来设置他们何时想要锁定方向,而不是依赖 App Delegate 通过迭代子视图或依赖继承来找到它们。
Swift 3
斯威夫特 3
In AppDelegate:
在 AppDelegate 中:
/// set orientations you want to be allowed in this property by default
var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.orientationLock
}
In some other global struct or helper class, here I created AppUtility:
在其他一些全局结构或辅助类中,我在这里创建了 AppUtility:
struct AppUtility {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
if let delegate = UIApplication.shared.delegate as? AppDelegate {
delegate.orientationLock = orientation
}
}
/// OPTIONAL Added method to adjust lock and rotate to the desired orientation
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
self.lockOrientation(orientation)
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
}
}
Then in the desired ViewController you want to lock orientations:
然后在您想要锁定方向的所需 ViewController 中:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
AppUtility.lockOrientation(.portrait)
// Or to rotate and lock
// AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Don't forget to reset when view is being removed
AppUtility.lockOrientation(.all)
}
回答by UIResponder
If your view is embedded in navigationcontroller in storyboard set the navigation controller delegate UINavigationControllerDelegate
and add the following method
如果您的视图嵌入在情节提要中的导航控制器中,请设置导航控制器委托UINavigationControllerDelegate
并添加以下方法
class ViewController: UIViewController, UINavigationControllerDelegate {
func navigationControllerSupportedInterfaceOrientations(navigationController: UINavigationController) -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
}
回答by Mu Sa
Same JasonJasonJasonanswer in Swift 4.2+(It worked correctly with iOS 11)
同样的JasonJasonJason在Swift 4.2+ 中回答(它在iOS 11 中正常工作)
1- Override shouldAutorotate and supportedInterfaceOrientations as shown below.
1- 覆盖 shouldAutorotate 和 supportedInterfaceOrientations,如下所示。
extension UINavigationController {
open override var shouldAutorotate: Bool {
return true
}
open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return (visibleViewController?.supportedInterfaceOrientations)!
}
}
2- And your main viewcontroller (portrait at all times), should have:
2- 您的主视图控制器(始终为肖像)应该具有:
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
3- Then, in your subviewcontrollers that you want to support portrait or landscape:
3- 然后,在您想要支持纵向或横向的子视图控制器中:
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.all
}
回答by superarts.org
Update: if you're having trouble to set orientation right after the app launches in iOS 10
, try do it in ObjC
instead of Swift
, and with class MyNavigationController: MyNavigationControllerBase
:
更新:如果您在应用程序启动后无法立即设置方向iOS 10
,请尝试在 中ObjC
而不是 中进行Swift
,并使用class MyNavigationController: MyNavigationControllerBase
:
@implementation ABNavigationControllerBase
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
@end
Swift 3:
斯威夫特 3:
class MyNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
}
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .portrait
}
}
回答by Daniel Sadka
The important think is to describe supported interface orientations for whole application in AppDelegate. For example to block all views to portrait just do this:
重要的想法是在 AppDelegate 中描述整个应用程序支持的界面方向。例如,要阻止所有视图到纵向,只需执行以下操作:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask{
return UIInterfaceOrientationMask.portrait
}
Lots of people are looking just for this answer by googling threw this question so I hope you can excuse me.
Works in Swift 3.0
很多人只是通过谷歌搜索来寻找这个答案,所以我希望你能原谅我。
适用于 Swift 3.0
回答by Saheb Roy
In the main controller where you want portrait,
在您想要肖像的主控制器中,
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.orientation = UIInterfaceOrientationMaskPortrait;
//Or self.orientation = UIInterfaceOrientationPortraitUpsideDown
}
and in subVC where you want Landscape use
并在您希望使用 Landscape 的 subVC 中
self.orientation = UIInterfaceOrientationLandscapeLeft:
self.orientation = UIInterfaceOrientationLandscapeRight:
or you can override this method
或者你可以覆盖这个方法
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
This is how i would do it with Obj-c in iOS7, i think this code would work in iOS8 too
这就是我在 iOS7 中使用 Obj-c 的方式,我认为这段代码也适用于 iOS8
回答by nbloqs
This is the syntax for Swift 3 (XCode 8.2 beta), where these methods where converted to properties:
这是 Swift 3 (XCode 8.2 beta) 的语法,其中这些方法转换为属性:
extension UINavigationController {
override open var shouldAutorotate: Bool {
return false
}
}
class ViewController: UIViewController {
/*
...
*/
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
}
回答by Chathuranga Silva
Here is the Swift Update :-
这是 Swift 更新:-
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
回答by mesopotamia
Edited for swift2.0 :
为 swift2.0 编辑:
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return [.Portrait, .PortraitUpsideDown]
}