UIAlertController(actionSheet样式)取消按钮背景色不一致问题求助
问题:ActionSheet中取消按钮背景色与其他按钮不一致,如何统一?
我创建了一个preferredStyle为.actionSheet的UIAlertController,其中包含一个style为.cancel的取消按钮。从截图可见,取消按钮的背景色与其他按钮存在细微差异,且模拟器和真机上结果一致。以下是实现代码:
func showAlertWithThreeButtons(alertTitle: String, message: String, defaultTitle1: String, defaultTitle2: String, cancelTitle: String) { let alert = UIAlertController(title: alertTitle, message: message, preferredStyle: .actionSheet) let defaultAction = UIAlertAction(title: defaultTitle1, style: .default, handler: { (_) in self.baseDelegate?.defaultButtonPressed() }) let default2Action = UIAlertAction(title: defaultTitle2, style: .default, handler: { (_) in self.baseDelegate?.default2ButtonPressed() }) let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel, handler: { (_) in self.baseDelegate?.cancelButtonPressed() }) alert.setValue(NSAttributedString(string: alert.title!, attributes: [NSAttributedString.Key.font : UIFont.init(name: "SF Compact Display", size: 18) ?? UIFont.systemFont(ofSize: 18.0, weight: .regular), NSAttributedString.Key.foregroundColor : UIColor(named: "Grey#444444") ?? UIColor(red: 68/255, green: 68/255, blue: 68/255, alpha: 1)]), forKey: "attributedTitle") alert.setValue(NSAttributedString(string: alert.message!, attributes: [NSAttributedString.Key.font : UIFont.init(name: "SF Compact Display", size: 13) ?? UIFont.systemFont(ofSize: 13.0, weight: .regular), NSAttributedString.Key.foregroundColor : UIColor(named: "Grey#444444") ?? UIColor(red: 68/255, green: 68/255, blue: 68/255, alpha: 1)]), forKey: "attributedMessage") defaultAction.setValue(UIColor(named: "Blue#007AFF"), forKey: "titleTextColor") default2Action.setValue(UIColor(named: "Grey#444444"), forKey: "titleTextColor") cancelAction.setValue(UIColor(named: "Grey#444444"), forKey: "titleTextColor") alert.addAction(defaultAction) alert.addAction(default2Action) alert.addAction(cancelAction) self.present(alert, animated: true, completion: nil) }
解决方法
方法1:将取消按钮样式改为.default(推荐,无风险)
系统会对.cancel样式的按钮自动应用特殊视觉区分(包括背景色细微差异),如果不需要系统默认的取消行为(比如点击弹窗外部自动触发取消),可以直接修改取消按钮的样式为.default,并保证它是最后添加到AlertController的Action:
修改取消按钮的创建代码:
let cancelAction = UIAlertAction(title: cancelTitle, style: .default, handler: { (_) in self.baseDelegate?.cancelButtonPressed() })
这样所有按钮都会使用.default样式,背景色自然统一。
⚠️ 注意:改为.default后,点击ActionSheet外部不会自动触发取消操作。如果需要这个功能,需要手动给AlertController添加点击手势,或者选择方法2。
方法2:遍历子视图统一背景色(保留.cancel样式)
如果必须保留.cancel样式(比如依赖点击外部自动取消的行为),可以通过遍历AlertController的子视图,找到按钮背景并统一颜色。在present弹窗的completion回调中添加延迟执行的代码,确保视图加载完成:
修改present部分的代码:
self.present(alert, animated: true, completion: { DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // 递归遍历子视图,找出按钮背景视图 func findButtonBackgrounds(in view: UIView) -> [UIView] { var backgrounds = [UIView]() for subview in view.subviews { // 根据特征筛选按钮背景(高度大于40且有背景色) if subview.backgroundColor != nil && subview.frame.size.height > 40 { backgrounds.append(subview) } backgrounds.append(contentsOf: findButtonBackgrounds(in: subview)) } return backgrounds } let buttonBackgrounds = findButtonBackgrounds(in: alert.view) if let targetColor = buttonBackgrounds.first?.backgroundColor { // 将所有按钮背景色设为第一个按钮的背景色 buttonBackgrounds.forEach { $0.backgroundColor = targetColor } } } })
⚠️ 注意:这种方法依赖系统AlertController的内部视图结构,不同iOS版本可能失效,且存在一定的审核风险,建议优先使用方法1。
内容的提问来源于stack exchange,提问作者Louiza A
相关产品推荐
相关产品推荐

