如何在当前UIViewController之上展示高度约为屏幕80%的新控制器
解决半屏模态ViewController的展示问题
我懂你现在的烦恼——明明想在蓝色VC上方弹出一个占屏幕80%高度的红色ChartsVC,结果它总是全屏铺满,之前在viewDidLoad里调frame根本没用。问题主要出在两个点:一是布局时机不对,二是光靠overCurrentContext没法让系统识别你的自定义尺寸需求。
给你几个实用的解决办法,按需选择就行:
方法一:用iOS 13+自带的PageSheet样式(最简单)
这种方法不用折腾自定义布局,系统原生样式就能实现需求:
- 修改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)
- 要是想让底部的蓝色VC保持可见,记得在ChartsVC里设置
view.backgroundColor = .clear,把红色内容放在一个子容器View里,这样背景就能透出下面的VC了。
方法二:搭配overCurrentContext调整布局时机
如果你坚持要用overCurrentContext,那得把调整frame的代码移到viewDidLayoutSubviews里——因为viewDidLoad时View的布局还没完成,你设置的frame会被系统覆盖:
- 保持present的代码不变:
let additionalVC = ChartsViewController(currentSelection) additionalVC.modalPresentationStyle = .overCurrentContext present(additionalVC, animated: true)
- 在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] }
- 同样要设置
view.backgroundColor = .clear,把红色内容放在子View里,避免遮挡下方的蓝色VC。
方法三:自定义转场代理(更灵活)
如果上面的方法满足不了复杂需求(比如要自定义弹出动画),可以用代理精准控制:
- 在present时设置代理:
let additionalVC = ChartsViewController(currentSelection) additionalVC.modalPresentationStyle = .overCurrentContext additionalVC.presentationController?.delegate = self present(additionalVC, animated: true)
- 实现代理方法调整弹出区域:
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
相关产品推荐
相关产品推荐

