You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将已展示的模态视图控制器临时切换成全屏再恢复?

动态切换模态视图控制器的全屏/标准样式

直接用系统API就能实现,不用自定义容器或转场,核心是调整模态样式+配合视图动画,同时处理拖拽手势和视觉细节,以下是完整实现:

代码实现

class A: UIViewController {
    private var isFullScreen = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        presentationController?.delegate = self
    }

    @objc func goFullScreen(sender: UIButton) {
        guard !isFullScreen else { return }
        isFullScreen = true
        
        // 拦截拖拽关闭手势,隐藏顶部抓握条
        if let sheetPC = presentationController as? UISheetPresentationController {
            sheetPC.isModalInPresentation = true
            sheetPC.prefersGrabberVisible = false
        }
        
        // 切换为全屏模态样式
        modalPresentationStyle = .fullScreen
        
        // 动画过渡到全屏状态
        UIView.animate(withDuration: 0.3) {
            self.view.layer.cornerRadius = 0
            self.view.frame = UIScreen.main.bounds
            self.view.layoutIfNeeded()
        }
        
        // 这里添加你需要隐藏的UI操作
        // topToolbar.isHidden = true
    }   

    @objc func cancelFullScreen(sender: UIButton) {
        guard isFullScreen else { return }
        isFullScreen = false
        
        // 恢复拖拽关闭手势,显示顶部抓握条
        if let sheetPC = presentationController as? UISheetPresentationController {
            sheetPC.isModalInPresentation = false
            sheetPC.prefersGrabberVisible = true
        }
        
        // 切回标准pageSheet样式
        modalPresentationStyle = .pageSheet
        
        // 动画恢复到标准模态外观
        UIView.animate(withDuration: 0.3) {
            self.view.layer.cornerRadius = 16 // 系统默认pageSheet圆角
            self.view.frame = self.presentationController?.containerView?.bounds ?? self.view.frame
            self.view.layoutIfNeeded()
        }
        
        // 恢复显示UI元素
        // topToolbar.isHidden = false
    }         
}

// 实现代理控制拖拽关闭逻辑
extension A: UIAdaptivePresentationControllerDelegate {
    func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
        // 全屏状态下禁止拖拽关闭
        return !isFullScreen
    }
}

关键细节说明

  1. 模态样式切换:直接修改modalPresentationStyle后,用动画同步视觉变化,避免生硬跳转。系统会自动适配样式对应的布局容器,我们只需要调整自身view的frame和圆角即可。
  2. 拖拽手势控制:iOS 15+的标准模态由UISheetPresentationController实现,通过isModalInPresentation属性控制是否允许拖拽关闭,全屏时设为true拦截手势,恢复时设为false。同时隐藏/显示顶部抓握条增强视觉一致性。
  3. 视觉过渡:动画时长和系统模态过渡保持一致(0.3秒),圆角设为系统默认的16pt,保证和原生模态外观统一。
  4. 保持同一实例:全程不需要dismiss再present,所有修改都在当前VC上完成,确保状态不丢失。

注意点

  • 如果需要兼容iOS 14及以下,标准模态的底层是UIPresentationController,可以直接修改containerView的布局,或者用AutoLayout约束代替直接设置frame,避免适配问题。
  • 若使用AutoLayout,动画时只需要修改约束常量,然后调用layoutIfNeeded()即可,比直接设置frame更稳定。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:15:54