iPad端FormSheet样式Sheet不遵循preferedContentSize问题咨询
适配不同尺寸类的Sheet展示方案
核心实现思路
按设备尺寸类分支处理:
- 紧凑尺寸类(iPhone):用
UISheetPresentationController配置自定义detents实现底部Sheet - 常规尺寸类(iPad):强制使用FormSheet悬浮样式,通过修改布局约束实现近乎全屏效果,忽略
preferredContentSize
代码实现
1. 通用Sheet展示工具方法
func presentCustomSheet(_ targetVC: UIViewController, from presenter: UIViewController) { switch presenter.traitCollection.horizontalSizeClass { case .compact: targetVC.modalPresentationStyle = .pageSheet guard let sheet = targetVC.sheetPresentationController else { presenter.present(targetVC, animated: true) return } // 自定义detents:半屏+全屏,可按需调整 sheet.detents = [ .custom(resolver: { $0.maximumDetentValue * 0.5 }), .large() ] sheet.prefersGrabberVisible = true default: targetVC.modalPresentationStyle = .formSheet targetVC.modalTransitionStyle = .coverVertical targetVC.presentationController?.delegate = presenter } presenter.present(targetVC, animated: true) }
2. 实现代理调整iPad布局
在负责展示的ViewController中添加代理扩展:
extension YourPresenterVC: UIAdaptivePresentationControllerDelegate { func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { return .none // 保留FormSheet样式,禁止系统自动适配 } func presentationControllerDidPresent(_ presentationController: UIPresentationController) { guard let presentedView = presentationController.presentedViewController.view, let container = presentationController.containerView else { return } // 清除原有尺寸约束 presentedView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.deactivate(presentedView.constraints) // 设置新约束,仅留边距(此处设为20pt,可修改) let edgeMargin: CGFloat = 20 NSLayoutConstraint.activate([ presentedView.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: edgeMargin), presentedView.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -edgeMargin), presentedView.topAnchor.constraint(equalTo: container.topAnchor, constant: edgeMargin), presentedView.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -edgeMargin) ]) } }
3. 注意事项
- iPad端必须设置
modalPresentationStyle = .formSheet,才能保证弹窗悬浮显示 - 通过
presentationControllerDidPresent修改约束,直接覆盖系统基于preferredContentSize生成的布局 - 紧凑尺寸类的detents可根据需求增减档位或调整比例
内容的提问来源于stack exchange,提问作者Warpling
相关产品推荐
相关产品推荐

