Arm*_*uer 11 xcode rotation uiviewcontroller ios swift
我正在尝试旋转一个视图,而所有其他视图(5)都固定为纵向.原因是在一个视图中我希望用户观看他之前保存的图片.我想这是可能的,但到目前为止我无法弄清楚如何实现这一目标.任何人都可以帮忙或给我一个暗示吗?我正在使用在iOS8上运行的Swift编程
Lyn*_*ott 31
我建议supportedInterfaceOrientationsForWindow您appDelegate只在特定的视图控制器中使用以允许旋转,例如:
斯威夫特3 <
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
// Make sure the root controller has been set
// (won't initially be set when the app is launched)
if let navigationController = self.window?.rootViewController as? UINavigationController {
// If the visible view controller is the
// view controller you'd like to rotate, allow
// that window to support all orientations
if navigationController.visibleViewController is SpecificViewController {
return UIInterfaceOrientationMask.all
}
// Else only allow the window to support portrait orientation
else {
return UIInterfaceOrientationMask.portrait
}
}
// If the root view controller hasn't been set yet, just
// return anything
return UIInterfaceOrientationMask.portrait
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果在转到纵向屏幕之前该特定视图控件处于横向状态,则另一个视图仍将以横向打开.为了避免这种情况,我建议在该视图处于横向状态时禁止转换.
斯威夫特4
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
// Make sure the root controller has been set
// (won't initially be set when the app is launched)
if let navigationController = self.window?.rootViewController as? UINavigationController {
// If the visible view controller is the
// view controller you'd like to rotate, allow
// that window to support all orientations
if navigationController.visibleViewController is SpecificViewController {
return Int(UIInterfaceOrientationMask.All.rawValue)
}
// Else only allow the window to support portrait orientation
else {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
}
// If the root view controller hasn't been set yet, just
// return anything
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
Run Code Online (Sandbox Code Playgroud)
您也可以以面向协议的方式执行此操作.只需创建协议
protocol CanRotate {
}
Run Code Online (Sandbox Code Playgroud)
在AppDelegate中以更"swifty"的方式添加相同的2个方法
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if topViewController(in: window?.rootViewController) is CanRotate {
return .allButUpsideDown
} else {
return .portrait
}
}
func topViewController(in rootViewController: UIViewController?) -> UIViewController? {
guard let rootViewController = rootViewController else {
return nil
}
if let tabBarController = rootViewController as? UITabBarController {
return topViewController(in: tabBarController.selectedViewController)
} else if let navigationController = rootViewController as? UINavigationController {
return topViewController(in: navigationController.visibleViewController)
} else if let presentedViewController = rootViewController.presentedViewController {
return topViewController(in: presentedViewController)
}
return rootViewController
}
Run Code Online (Sandbox Code Playgroud)
在每个想要不同行为的ViewController中,只需在类的定义中添加协议名称即可.
class ViewController: UIViewController, CanRotate {}
Run Code Online (Sandbox Code Playgroud)
如果您想要任何特定组合,您可以向协议添加要覆盖的变量
protocol CanRotate {
var supportedInterfaceOrientations: UIInterfaceOrientationMask
}
Run Code Online (Sandbox Code Playgroud)
有时,当您使用自定义导航流(可能会变得非常复杂)时,上述解决方案可能并不总是有效。此外,如果您有多个需要支持多个方向的 ViewController,它可能会变得非常乏味。
这是我找到的一个相当快速的解决方案。定义一个类OrientationManager并使用它来更新 AppDelegate 中支持的方向:
class OrientationManager {
static var landscapeSupported: Bool = false
}
Run Code Online (Sandbox Code Playgroud)
然后在 AppDelegate 中放置您想要的特定情况的方向:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if OrientationManager.landscapeSupported {
return .allButUpsideDown
}
return .portrait
}
Run Code Online (Sandbox Code Playgroud)
然后在您想要多个导航的 ViewControllers 中更新OrientationManager:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
OrientationManager.landscapeSupported = true
}
Run Code Online (Sandbox Code Playgroud)
另外,当您退出此 ViewController 时,不要忘记再次更新它:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
OrientationManager.landscapeSupported = false
//The code below will automatically rotate your device's orientation when you exit this ViewController
let orientationValue = UIInterfaceOrientation.portrait.rawValue
UIDevice.current.setValue(orientationValue, forKey: "orientation")
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
更新:
您可能只想static func在Orientation Support Manager类中添加一个:
static func setOrientation(_ orientation: UIInterfaceOrientation) {
let orientationValue = orientation.rawValue
UIDevice.current.setValue(orientationValue, forKey: "orientation")
landscapeSupported = orientation.isLandscape
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在需要将方向重新设置为纵向时调用此函数。这也将更新静态landscapeSupported值:
OSM.setOrientation(.portrait)
Run Code Online (Sandbox Code Playgroud)
根据每个人的想法,我写了我认为最优雅的方法。
结果:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return (UIApplication.getTopViewController() as? Rotatable == nil) ? .portrait : .allButUpsideDown
}
Run Code Online (Sandbox Code Playgroud)
将此扩展添加到您的项目中,这不仅对此有用:
extension UIApplication {
class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return getTopViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return getTopViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return getTopViewController(base: presented)
}
return base
}
}
Run Code Online (Sandbox Code Playgroud)
创建协议:
protocol Rotatable {}
Run Code Online (Sandbox Code Playgroud)
并实施它:
class ViewController: UIViewController, Rotatable {
}
Run Code Online (Sandbox Code Playgroud)
这是针对Swift 3和Swift 4的。您可以在AppDelegate.swift中使用以下代码:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
guard let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController),
(rootViewController.responds(to: Selector(("canRotate")))) else{
// Only allow portrait (standard behaviour)
return .portrait;
}
// Unlock landscape view orientations for this view controller
return .allButUpsideDown;
}
private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
guard rootViewController != nil else { return nil }
guard !(rootViewController.isKind(of: (UITabBarController).self)) else{
return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController)
}
guard !(rootViewController.isKind(of:(UINavigationController).self)) else{
return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController)
}
guard !(rootViewController.presentedViewController != nil) else{
return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
}
return rootViewController
}
Run Code Online (Sandbox Code Playgroud)
您可以在原始帖子中了解更多信息:http : //www.jairobjunior.com/blog/2016/03/05/how-to-rotate-only-one-view-controller-to-landscape-in-ios-slash -迅速/
| 归档时间: |
|
| 查看次数: |
10958 次 |
| 最近记录: |