iOS13中UIAlertController(actionSheet样式)自定义视图灰度化问题求助
解决iOS13中UIAlertController ActionSheet自定义视图灰度化问题
首先明确:这是iOS13系统对.actionSheet样式UIAlertController的设计变更,并非Bug——系统为了统一actionSheet的视觉风格,强制对其内部的自定义视图应用了灰度化的色调调整。下面给你几个不用弃用UIAlertController的可行方案:
方案1:强制解除子控件的灰度化调整
在present alertController之后,遍历自定义视图的所有子控件,将它们的tintAdjustmentMode设置为.normal,就能绕过系统的灰度化处理,同时保留actionSheet的原有布局:
let sheet = UIAlertController(customView: awesomeView, preferredStyle: .actionSheet) present(sheet, animated: true) { // 递归遍历所有子视图,解除灰度化限制 func removeGrayscale(from view: UIView) { view.tintAdjustmentMode = .normal view.subviews.forEach(removeGrayscale) } removeGrayscale(from: awesomeView) }
这个方案简单直接,能快速恢复自定义视图的颜色表现,几乎不需要修改原有布局。
方案2:自定义Popover模拟ActionSheet布局
如果方案1在某些复杂场景下有兼容性问题,你可以利用UIPopoverPresentationController实现一个自定义弹出视图,完全模拟系统actionSheet的底部弹出样式,同时完全掌控视图的视觉样式:
// 创建自定义容器视图控制器 class CustomActionSheetVC: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground view.layer.cornerRadius = 12 // 模拟系统actionSheet的圆角样式 // 添加自定义视图到容器 awesomeView.frame = view.bounds awesomeView.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(awesomeView) } override var preferredContentSize: CGSize { get { awesomeView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) } set { super.preferredContentSize = newValue } } } // 弹出自定义视图 let customSheet = CustomActionSheetVC() customSheet.modalPresentationStyle = .popover if let popover = customSheet.popoverPresentationController { popover.sourceView = self.view popover.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.maxY, width: 0, height: 0) popover.permittedArrowDirections = .down popover.delegate = self } present(customSheet, animated: true)
记得实现UIPopoverPresentationControllerDelegate方法,确保在iPhone上实现底部全屏弹出的效果:
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { return .overFullScreen // 按需选择.fullScreen或.overFullScreen }
这个方案自由度最高,完全不受系统样式限制,还能自定义弹出动画、边缘间距等细节。
方案3:动态切换样式并适配布局
如果你的自定义视图布局比较简单,也可以在iOS13及以上动态切换为.alert样式,再通过调整布局约束模拟actionSheet的视觉效果:
let style: UIAlertController.Style if #available(iOS 13.0, *) { style = .alert } else { style = .actionSheet } let sheet = UIAlertController(customView: awesomeView, preferredStyle: style) // 在iOS13下调整alert的尺寸,模拟actionSheet的宽度 if #available(iOS 13.0, *) { sheet.preferredContentSize = CGSize(width: view.bounds.width, height: awesomeView.bounds.height) } present(sheet, animated: true)
这个方案适配成本最低,适合布局逻辑不复杂的自定义视图场景。
内容的提问来源于stack exchange,提问作者Konstantin Loginov
相关产品推荐
相关产品推荐

