仅在一个ViewController中旋转

Arm*_*uer 11 xcode rotation uiviewcontroller ios swift

我正在尝试旋转一个视图,而所有其他视图(5)都固定为纵向.原因是在一个视图中我希望用户观看他之前保存的图片.我想这是可能的,但到目前为止我无法弄清楚如何实现这一目标.任何人都可以帮忙或给我一个暗示吗?我正在使用在iOS8上运行的Swift编程

Lyn*_*ott 31

我建议supportedInterfaceOrientationsForWindowappDelegate只在特定的视图控制器中使用以允许旋转,例如:

斯威夫特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)


Cri*_*ena 8

您也可以以面向协议的方式执行此操作.只需创建协议

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)


Nik*_*der 8

有时,当您使用自定义导航流(可能会变得非常复杂)时,上述解决方案可能并不总是有效。此外,如果您有多个需要支持多个方向的 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 funcOrientation 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)


Mic*_*sen 8

根据每个人的想法,我写了我认为最优雅的方法。

结果:

    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)


gan*_*ena 5

这是针对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 次

最近记录:

6 年,7 月 前