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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:25:46