You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS开发:如何让模态呈现的ViewController可旋转,呈现者固定竖屏?

实现模态ViewController可旋转、发起ViewController保持固定方向的方案

你当前通过AppDelegate全局控制方向锁的思路是可行的,要实现模态页单独旋转的需求,只需要在模态呈现前后动态调整全局方向锁,再结合ViewController自身的旋转权限配置即可,具体步骤如下:

1. 完善OrientationManager工具类

先把你的OrientationManager补全,方便全局统一控制方向锁:

struct OrientationManager {
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
        guard let delegate = UIApplication.shared.delegate as? AppDelegate else { return }
        delegate.orientationLock = orientation
    }
    
    // 可选方法:强制刷新当前屏幕方向,确保设置立即生效
    static func forceOrientationRefresh() {
        UIViewController.attemptRotationToDeviceOrientation()
    }
}

2. 在发起呈现的ViewController中做状态切换

在弹出模态页的ViewController里,呈现前解锁允许旋转的方向,模态页消失后恢复竖屏锁定:

class PresentingViewController: UIViewController {
    // 示例:点击按钮弹出模态页
    @IBAction func showModalVC(_ sender: UIButton) {
        let modalVC = ModalViewController()
        // 呈现前允许模态页支持的方向(比如除了倒过来的所有方向)
        OrientationManager.lockOrientation(.allButUpsideDown)
        present(modalVC, animated: true)
        
        // 监听模态页消失事件,用于恢复方向锁
        modalVC.presentationController?.delegate = self
    }
}

// 实现UIAdaptivePresentationControllerDelegate处理消失逻辑
extension PresentingViewController: UIAdaptivePresentationControllerDelegate {
    func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
        // 模态页关闭后,恢复竖屏锁定
        OrientationManager.lockOrientation(.portrait)
        OrientationManager.forceOrientationRefresh()
    }
}

3. 配置模态ViewController的旋转权限

在你的模态ViewController里,明确声明它支持的旋转方向,让系统知道它可以响应旋转:

class ModalViewController: UIViewController {
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        // 这里设置你允许的方向,比如.allButUpsideDown或者仅横屏.landscape
        return .allButUpsideDown
    }
    
    override var shouldAutorotate: Bool {
        return true
    }
}

4. 容器类适配(可选)

如果你的项目用了UINavigationControllerUITabBarController这类容器,需要给它们添加扩展,让它们转发子ViewController的旋转设置,避免容器拦截旋转请求:

extension UINavigationController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return topViewController?.supportedInterfaceOrientations ?? .portrait
    }
    
    override open var shouldAutorotate: Bool {
        return topViewController?.shouldAutorotate ?? false
    }
}

extension UITabBarController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return selectedViewController?.supportedInterfaceOrientations ?? .portrait
    }
    
    override open var shouldAutorotate: Bool {
        return selectedViewController?.shouldAutorotate ?? false
    }
}

这样设置后,弹出模态页时设备可以自由旋转到允许的方向;模态页关闭后,发起的ViewController会立刻回到竖屏并保持锁定状态,不会跟着设备旋转。

内容的提问来源于stack exchange,提问作者Tometoyou

火山引擎 最新活动