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

如何在当前UIViewController之上展示高度约为屏幕80%的新控制器

解决半屏模态ViewController的展示问题

我懂你现在的烦恼——明明想在蓝色VC上方弹出一个占屏幕80%高度的红色ChartsVC,结果它总是全屏铺满,之前在viewDidLoad里调frame根本没用。问题主要出在两个点:一是布局时机不对,二是光靠overCurrentContext没法让系统识别你的自定义尺寸需求。

给你几个实用的解决办法,按需选择就行:

方法一:用iOS 13+自带的PageSheet样式(最简单)

这种方法不用折腾自定义布局,系统原生样式就能实现需求:

  1. 修改present前的配置代码:
let additionalVC = ChartsViewController(currentSelection)
// 改用pageSheet样式,支持自定义尺寸
additionalVC.modalPresentationStyle = .pageSheet
// 设置目标尺寸,这里取屏幕高度的80%
additionalVC.preferredContentSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.8)
present(additionalVC, animated: true)
  1. 要是想让底部的蓝色VC保持可见,记得在ChartsVC里设置view.backgroundColor = .clear,把红色内容放在一个子容器View里,这样背景就能透出下面的VC了。

方法二:搭配overCurrentContext调整布局时机

如果你坚持要用overCurrentContext,那得把调整frame的代码移到viewDidLayoutSubviews里——因为viewDidLoad时View的布局还没完成,你设置的frame会被系统覆盖:

  1. 保持present的代码不变:
let additionalVC = ChartsViewController(currentSelection)
additionalVC.modalPresentationStyle = .overCurrentContext
present(additionalVC, animated: true)
  1. 在ChartsViewController里重写布局方法:
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let screenBounds = UIScreen.main.bounds
    let targetHeight = screenBounds.height * 0.8
    // 这里把VC放在屏幕底部,你也可以改成居中,按需调整y值
    self.view.frame = CGRect(x: 0, y: screenBounds.height - targetHeight, width: screenBounds.width, height: targetHeight)
    // 可选:给顶部加圆角,视觉效果更友好
    self.view.layer.cornerRadius = 16
    self.view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
}
  1. 同样要设置view.backgroundColor = .clear,把红色内容放在子View里,避免遮挡下方的蓝色VC。

方法三:自定义转场代理(更灵活)

如果上面的方法满足不了复杂需求(比如要自定义弹出动画),可以用代理精准控制:

  1. 在present时设置代理:
let additionalVC = ChartsViewController(currentSelection)
additionalVC.modalPresentationStyle = .overCurrentContext
additionalVC.presentationController?.delegate = self
present(additionalVC, animated: true)
  1. 实现代理方法调整弹出区域:
extension YourCurrentViewController: UIAdaptivePresentationControllerDelegate {
    // 禁用自适应全屏
    func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        return .none
    }
    
    // 自定义弹出View的frame
    func presentationController(_ controller: UIPresentationController, frameOfPresentedViewInContainerView containerView: UIView) -> CGRect {
        let screenBounds = containerView.bounds
        let targetHeight = screenBounds.height * 0.8
        return CGRect(x: 0, y: screenBounds.height - targetHeight, width: screenBounds.width, height: targetHeight)
    }
}

这种方式能精准控制弹出VC的位置和尺寸,适合个性化需求的场景。

测试的时候记得兼顾不同屏幕尺寸,尽量用UIScreen.main.bounds或者containerView.bounds计算,别写固定数值哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:50:15