Thi*_*ung 81 portrait uiviewcontroller device-orientation swift
由于我的应用得到了所有方向的支持.我想只将肖像模式锁定到特定的UIViewController.
(例如,假设它是Tabbed应用程序,当SignIn View以模态方式出现时,我只想将SignIn View设置为纵向模式,无论用户如何旋转设备或当前设备方向如何)
bmj*_*hns 215
当您拥有复杂的视图层次结构时,例如拥有多个导航控制器和/或选项卡视图控制器,事情就会变得非常混乱.
此实现将其置于各个视图控制器上以设置何时锁定方向,而不是依靠App Delegate通过迭代子视图来查找它们.
斯威夫特3和4
在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
}
在其他一些全局struct或helper类中,我在这里创建了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")
        UINavigationController.attemptRotationToDeviceOrientation()
    }
}
然后在所需的ViewController中,您想要锁定方向:
 override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(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)
}
如果是iPad或Universal App
确保在目标设置 - >常规 - >部署信息中选中"需要全屏".supportedInterfaceOrientationsFor如果未选中,则不会调用delegate.

Nah*_*han 22
斯威夫特4
var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return self.orientationLock
}
struct AppUtility {
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
        self.lockOrientation(orientation)
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }
}
如果只需要纵向方向,则ViewController添加以下行.你必须将此应用于所有ViewController需要显示肖像模式.
override func viewWillAppear(_ animated: Bool) {
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait)
    }
这将根据设备的物理方向为其他ViewController制作屏幕方向.
override func viewWillDisappear(_ animated: Bool) {
        AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.all)
    }
小智 13
对于新版本的 Swift 试试这个
override var shouldAutorotate: Bool {
    return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}
添加此代码以强制纵向并锁定它:
override func viewDidLoad() {
    super.viewDidLoad()
    // Force the device in portrait mode when the view controller gets loaded
    UIDevice.currentDevice().setValue(UIInterfaceOrientation.Portrait.rawValue, forKey: "orientation") 
}
override func shouldAutorotate() -> Bool {
    // Lock autorotate
    return false
}
override func supportedInterfaceOrientations() -> Int {
    // Only allow Portrait
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    // Only allow Portrait
    return UIInterfaceOrientation.Portrait
}
在AppDelegate中 - 将supportedInterfaceOrientationsForWindow设置为您希望整个应用程序支持的任何方向:
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.All
} 
这是您的问题和其他相关问题的通用解决方案。
1.创建辅助类UIHelper并使用以下方法:
    /**This method returns top view controller in application  */
    class func topViewController() -> UIViewController?
    {
        let helper = UIHelper()
        return helper.topViewControllerWithRootViewController(rootViewController: UIApplication.shared.keyWindow?.rootViewController)
    }
    /**This is a recursive method to select the top View Controller in a app, either with TabBarController or not */
    private func topViewControllerWithRootViewController(rootViewController:UIViewController?) -> UIViewController?
    {
        if(rootViewController != nil)
        {
            // UITabBarController
            if let tabBarController = rootViewController as? UITabBarController,
                let selectedViewController = tabBarController.selectedViewController {
                return self.topViewControllerWithRootViewController(rootViewController: selectedViewController)
            }
            // UINavigationController
            if let navigationController = rootViewController as? UINavigationController ,let visibleViewController = navigationController.visibleViewController {
                return self.topViewControllerWithRootViewController(rootViewController: visibleViewController)
            }
            if ((rootViewController!.presentedViewController) != nil) {
                let presentedViewController = rootViewController!.presentedViewController;
                return self.topViewControllerWithRootViewController(rootViewController: presentedViewController!);
            }else
            {
                return rootViewController
            }
        }
        return nil
    }
2.根据您的期望行为创建协议,因为您的具体情况将是纵向的。
协议方向IsOnlyPortrait {}
注意:如果需要,可将其添加到UIHelper类的顶部。
3.扩展您的View Controller
在您的情况下:
class Any_ViewController: UIViewController,orientationIsOnlyPortrait {
   ....
}
4.在应用程序委托类中,添加以下方法:
 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        let presentedViewController = UIHelper.topViewController()
        if presentedViewController is orientationIsOnlyPortrait {
            return .portrait
        }
        return .all
    }
最后说明:
Swift 3 & 4
Set the supportedInterfaceOrientations property of specific UIViewControllers like this: 
class MyViewController: UIViewController {
    var orientations = UIInterfaceOrientationMask.portrait //or what orientation you want
    override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    get { return self.orientations }
    set { self.orientations = newValue }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    //...
}
UPDATE
This solution only works when your viewController is not embedded in UINavigationController, because the orientation inherits from parent viewController.
For this case, you can create a subclass of UINavigationViewController and set these properties on it.
在该线程中有很多很好的答案,但没有一个完全符合我的需求。我有一个选项卡式应用程序,每个选项卡中都有导航控制器,一个视图需要旋转,而其他视图则需要纵向锁定。出于某种原因,导航控制器未正确调整其子视图的大小。结合此答案找到了解决方案(在Swift 3中),布局问题消失了。按照@bmjohns的建议创建结构:
import UIKit
struct OrientationLock {
    static func lock(to orientation: UIInterfaceOrientationMask) {
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }
    static func lock(to orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation) {
        self.lock(to: orientation)
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }
} 
然后子类UITabBarController:
    import UIKit
class TabBarController: UITabBarController, UITabBarControllerDelegate {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.delegate = self
    }
    func tabBarControllerSupportedInterfaceOrientations(_ tabBarController: UITabBarController) -> UIInterfaceOrientationMask {
        if tabBarController.selectedViewController is MyViewControllerNotInANavigationControllerThatShouldRotate {
            return .allButUpsideDown
        } else if let navController = tabBarController.selectedViewController as? UINavigationController, navController.topViewController is MyViewControllerInANavControllerThatShouldRotate {
            return .allButUpsideDown
        } else {
            //Lock view that should not be able to rotate
            return .portrait
        }
    }
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        if viewController is MyViewControllerNotInANavigationControllerThatShouldRotate {
            OrientationLock.lock(to: .allButUpsideDown)
        } else if let navController = viewController as? UINavigationController, navController.topViewController is MyViewControllerInANavigationControllerThatShouldRotate {
            OrientationLock.lock(to: .allButUpsideDown)
        } else {
            //Lock orientation and rotate to desired orientation
            OrientationLock.lock(to: .portrait, andRotateTo: .portrait)
        }
        return true
    }
}
不要忘记将情节提要中TabBarController的类更改为新创建的子类。
小智 5
对于 iOS 16,接受的答案不起作用。但能够让它工作。只需更换
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
有了这个,
if #available(iOS 16.0, *) {
        guard
            let rootViewController = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController,
            let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
        else { return }
        rootViewController.setNeedsUpdateOfSupportedInterfaceOrientations()
        windowScene.requestGeometryUpdate(.iOS(
            interfaceOrientations: windowScene.interfaceOrientation.isLandscape
                ? .portrait
                : .landscapeRight
        ))
    } else {
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }
| 归档时间: | 
 | 
| 查看次数: | 80375 次 | 
| 最近记录: |