我试图在横向模式的应用程序中强制只有一个视图, 我在打电话
override func shouldAutorotate() -> Bool {
print("shouldAutorotate")
return false
}
override func supportedInterfaceOrientations() -> Int {
print("supportedInterfaceOrientations")
return Int(UIInterfaceOrientationMask.LandscapeLeft.rawValue)
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
return UIInterfaceOrientation.LandscapeLeft
}
视图以纵向模式启动,并在更改设备方向时保持旋转。
永远不会调用shouldAutorotate
任何帮助将不胜感激。
答案 0 :(得分:60)
它可能对其他人有用,我找到了一种强制视图以横向模式启动的方法:
将它放在viewDidLoad()中:
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
和
override var shouldAutorotate: Bool {
return true
}
答案 1 :(得分:46)
override func viewDidLoad() {
super.viewDidLoad()
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeLeft
}
override var shouldAutorotate: Bool {
return true
}
//如果您的视图嵌入在导航控制器中,则仅上述操作无效。你必须级联 //所以在类定义
之后添加以下扩展名extension UINavigationController {
override open var shouldAutorotate: Bool {
get {
if let visibleVC = visibleViewController {
return visibleVC.shouldAutorotate
}
return super.shouldAutorotate
}
}
override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
get {
if let visibleVC = visibleViewController {
return visibleVC.preferredInterfaceOrientationForPresentation
}
return super.preferredInterfaceOrientationForPresentation
}
}
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
get {
if let visibleVC = visibleViewController {
return visibleVC.supportedInterfaceOrientations
}
return super.supportedInterfaceOrientations
}
}}
override func viewDidLoad() {
super.viewDidLoad()
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
private func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscapeLeft
}
private func shouldAutorotate() -> Bool {
return true
}
答案 2 :(得分:19)
Swift 4 ,测试 iOS 11
您可以在 projectTarget - >中指定方向一般 - > DeploymentInfo(设备方向) - >肖像(Landscapeleft和Landscaperight是可选的)
<强>的AppDelegate 强>
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return myOrientation
}
<强> LandScpaeViewController 强>
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myOrientation = .landscape
}
<强> OnDismissButtonTap 强>
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myOrientation = .portrait
多数民众赞成。 :)
答案 3 :(得分:18)
使用Swift 2.2
尝试:
let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
跟着:
UIViewController.attemptRotationToDeviceOrientation()
来自Apple的UIViewController类参考:
某些视图控制器可能希望使用特定于应用程序的条件来确定支持哪些接口方向。如果您的视图控制器执行此操作,当这些条件发生更改时,您的应用程序应调用此类方法。系统会立即尝试旋转到新方向。
然后,正如其他人所建议的那样,根据需要覆盖以下方法:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.LandscapeLeft
}
override func shouldAutorotate() -> Bool {
return true
}
我在签名视图中遇到了类似的问题,这为我解决了这个问题。
答案 4 :(得分:9)
对我来说,最好的结果来自Zeesha的回答和sazz的回答。
将以下行添加到AppDelegate.swift:
var orientationLock = UIInterfaceOrientationMask.portrait
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return myOrientation
}
将以下行添加到视图控制器类:
let appDel = UIApplication.shared.delegate as! AppDelegate
将以下行添加到视图控制器的viewDidLoad()
:
appDel.myOrientation = .landscape
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
(可选)将此行添加到您的解散功能:
appDel.myOrientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
这些代码行的作用是将默认方向设置为纵向,在视图控制器加载时将其旋转,然后在视图控制器关闭后最终将其重置为纵向。
答案 5 :(得分:6)
我需要强制一个控制器进入纵向。添加这个对我有用。
使用iOS 11的swift 4
override var supportedInterfaceOrientations : UIInterfaceOrientationMask{
return .portrait
}
答案 6 :(得分:4)
覆盖(在ViewController中):
override public var shouldAutorotate: Bool {
return false
}
override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeRight
}
override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
ios 13的提示从ios 13开始,VC与modalPresentationStyle
具有不同的.automatic
,并且设备存在模式视图而不是全屏VC。要解决此问题,必须将modalPresentationStyle
设置为.fullScreen
。示例:
let viewController = YourViewController()
viewController.modalPresentationStyle = .fullScreen
答案 7 :(得分:2)
Swift 3.每次用户重新打开应用程序时,都会锁定方向。
class MyViewController: UIViewController {
...
override func viewDidLoad() {
super.viewDidLoad()
// Receive notification when app is brought to foreground
NotificationCenter.default.addObserver(self, selector: #selector(self.onDidBecomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
}
// Handle notification
func onDidBecomeActive() {
setOrientationLandscape()
}
// Change orientation to landscape
private func setOrientationLandscape() {
if !UIDevice.current.orientation.isLandscape {
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey:"orientation")
UIViewController.attemptRotationToDeviceOrientation()
}
}
// Only allow landscape left
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscapeLeft
}
/*
// Allow rotation - this seems unnecessary
private func shouldAutoRotate() -> Bool {
return true
}
*/
...
}
答案 8 :(得分:2)
适用于Swift 2.2
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
if self.window?.rootViewController?.presentedViewController is SignatureViewController {
let secondController = self.window!.rootViewController!.presentedViewController as! SignatureViewController
if secondController.isPresented {
return UIInterfaceOrientationMask.LandscapeLeft;
} else {
return UIInterfaceOrientationMask.Portrait;
}
} else {
return UIInterfaceOrientationMask.Portrait;
}
}
答案 9 :(得分:1)
Swift 4
尝试保持方向不起作用,但这对我来说:
...
override func viewDidLoad() {
super.viewDidLoad()
forcelandscapeRight()
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(forcelandscapeRight), name: Notification.Name.UIDeviceOrientationDidChange, object: nil)
}
@objc func forcelandscapeRight() {
let value = UIInterfaceOrientation.landscapeRight.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
....
答案 10 :(得分:1)
在ViewController中的viewDidLoad方法下方的函数调用
func rotateDevice(){
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UIView.setAnimationsEnabled(true) // while rotating device it will perform the rotation animation
}`
App委托文件在函数和变量下方添加
//Orientation Variables
var orientationLock = UIInterfaceOrientationMask.portrait
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return .landscape }
答案 11 :(得分:0)
根据documentation of supportedInterfaceOrientations,shouldAutorotate
方法应在Objective-C中返回true
或YES
,以便考虑supportedInterfaceOrientations
。
答案 12 :(得分:0)
我的解决方法是
仅在AppDelegate中的代码下面添加了
enum PossibleOrientations {
case portrait
case landscape
func o() -> UIInterfaceOrientationMask {
switch self {
case .portrait:
return .portrait
case .landscape:
return .landscapeRight
}
}
}
var orientation: UIInterfaceOrientationMask = .portrait
func switchOrientation(to: PossibleOrientations) {
let keyOrientation = "orientation"
if to == .portrait && UIDevice.current.orientation.isPortrait {
return
} else if to == .landscape && UIDevice.current.orientation.isLandscape {
return
}
switch to {
case .portrait:
orientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: keyOrientation)
case .landscape:
orientation = .landscapeRight
UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: keyOrientation)
}
}
并调用以下代码进行更改
override func viewDidLoad() {
super.viewDidLoad()
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.switchOrientation(to: .landscape)
}
}
或如下所示
@IBAction func actBack() {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.switchOrientation(to: .portrait)
}
self.navigationController?.popViewController(animated: true)
}
答案 13 :(得分:0)
// below code put in view controller
// you can change landscapeLeft or portrait
override func viewWillAppear(_ animated: Bool) {
UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")
}
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeRight
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
答案 14 :(得分:0)
在AppDelegate中添加此
//Orientation Variables
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask
{
return myOrientation
}
将其添加到要更改方向的viewController中
override func viewDidLoad() {
super.viewDidLoad()
self.rotateToLandsScapeDevice()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.rotateToPotraitScapeDevice()
}
func rotateToLandsScapeDevice(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myOrientation = .landscapeLeft
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UIView.setAnimationsEnabled(true)
}
func rotateToPotraitScapeDevice(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myOrientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UIView.setAnimationsEnabled(true)
}
答案 15 :(得分:0)
我在项目中遇到了类似的问题。它仅支持人像。 ViewController的结构是,Navigation包含一个控制器(我称为A)和一个A控制器中的长Scrollview。我需要A(纵向)到B(横向右边)。
在一开始,我尝试了下面的方法,它似乎可以工作,但最终我发现了一个错误。
Swift 5和iOS12
// In B controller just override three properties
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscapeRight
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
然后某些事情变得奇怪。当控制器B向控制器A撤消时。控制器A中的ScrollView已滑到某个点。
因此,我使用了另一种方法,因此在viewWillAppear
时旋转屏幕。您可以在下面查看其代码。
// In controller B
// not need override shouldAutorotate , supportedInterfaceOrientations , preferredInterfaceOrientationForPresentation
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let appDel = UIApplication.shared.delegate as! AppDelegate
appDel.currentOrientation = .landscapeRight
UIDevice.current.setValue( UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()
}
//in viewWillDisappear rotate to portrait can not fix the bug
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
let appDel = UIApplication.shared.delegate as! AppDelegate
appDel.currentOrientation = .portrait
UIDevice.current.setValue( UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation() //must call
super.dismiss(animated: true, completion: nil)
}
// in AppDelegate
// the info plist is only supported portrait also, No need to change it
var currentOrientation : UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.currentOrientation
}
答案 16 :(得分:0)
我尝试了以下许多答案,但恐怕它们没有用。特别是如果导航栏和标签栏也已在应用程序上实现。 Sunny Lee在以下文章中提供了对我有用的解决方案: Sunny Lee, Medium post
这是该帖子的更新: Original solution
实现帖子的解决方案时,我所做的唯一更改是将引用.allButUpsideDown的部分更改为.landscapeleft
答案 17 :(得分:0)
在带有Swift 5的Xcode 11中,我实现了以下内容。但是,仅当项目目标的设备方向未包括所有方向时,该方法才有效。我禁用了“颠倒”检查。在此之后,以下代码起作用。如果启用了所有复选框,则不会调用该代码;
class MyController : UINavigationController {
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscape
}
}
答案 18 :(得分:-3)
class CustomUIViewController : UIViewController{
override var supportedInterfaceOrientations : UIInterfaceOrientationMask{
return .landscapeLeft
}
}
class ViewController: CustomUIViewController {
.
.
.
}