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
}
Run Code Online (Sandbox Code Playgroud)
在其他一些全局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()
}
}
Run Code Online (Sandbox Code Playgroud)
然后在所需的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)
}
Run Code Online (Sandbox Code Playgroud)
如果是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")
}
}
Run Code Online (Sandbox Code Playgroud)
如果只需要纵向方向,则ViewController添加以下行.你必须将此应用于所有ViewController需要显示肖像模式.
override func viewWillAppear(_ animated: Bool) {
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait)
}
Run Code Online (Sandbox Code Playgroud)
这将根据设备的物理方向为其他ViewController制作屏幕方向.
override func viewWillDisappear(_ animated: Bool) {
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.all)
}
Run Code Online (Sandbox Code Playgroud)
小智 13
对于新版本的 Swift 试试这个
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return UIInterfaceOrientation.portrait
}
Run Code Online (Sandbox Code Playgroud)
添加此代码以强制纵向并锁定它:
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
}
Run Code Online (Sandbox Code Playgroud)
在AppDelegate中 - 将supportedInterfaceOrientationsForWindow设置为您希望整个应用程序支持的任何方向:
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.All
}
Run Code Online (Sandbox Code Playgroud)
这是您的问题和其他相关问题的通用解决方案。
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
}
Run Code Online (Sandbox Code Playgroud)
2.根据您的期望行为创建协议,因为您的具体情况将是纵向的。
协议方向IsOnlyPortrait {}
注意:如果需要,可将其添加到UIHelper类的顶部。
3.扩展您的View Controller
在您的情况下:
class Any_ViewController: UIViewController,orientationIsOnlyPortrait {
....
}
Run Code Online (Sandbox Code Playgroud)
4.在应用程序委托类中,添加以下方法:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
let presentedViewController = UIHelper.topViewController()
if presentedViewController is orientationIsOnlyPortrait {
return .portrait
}
return .all
}
Run Code Online (Sandbox Code Playgroud)
最后说明:
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()
}
//...
}
Run Code Online (Sandbox Code Playgroud)
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")
}
}
Run Code Online (Sandbox Code Playgroud)
然后子类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
}
}
Run Code Online (Sandbox Code Playgroud)
不要忘记将情节提要中TabBarController的类更改为新创建的子类。
小智 5
对于 iOS 16,接受的答案不起作用。但能够让它工作。只需更换
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
Run Code Online (Sandbox Code Playgroud)
有了这个,
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")
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
80375 次 |
| 最近记录: |