如何修改iOS UIContextMenu的背景色和UIAction文本的字体样式
实现方案
修改UIContextMenu背景色
你可以根据兼容版本选择对应的实现方式:
- 全局统一修改(推荐,无审核风险)
在AppDelegate的application(_:didFinishLaunchingWithOptions:)方法中添加以下代码:
if #available(iOS 14.0, *) { // iOS14+ 官方提供直接修改菜单背景的API UIMenuController.shared.menuBackgroundColor = .systemBlue // 替换为你的自定义颜色 } else { // iOS13 适配:通过外观代理修改菜单列表单元格背景 guard let menuListViewClass = NSClassFromString("_UIContextMenuListView") else { return } UITableViewCell.appearance(whenContainedInInstancesOf: [menuListViewClass]).backgroundColor = .systemBlue }
- 单页面单独修改
如果只需要修改当前页面的上下文菜单背景,可以实现UIContextMenuInteractionDelegate的willDisplay回调,在菜单弹出时遍历视图修改背景:
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willDisplay menu: UIMenu, forConfiguration configuration: UIContextMenuConfiguration) { DispatchQueue.main.async { // 查找上下文菜单对应的窗口 guard let menuWindow = UIApplication.shared.windows.first(where: { NSStringFromClass(type(of: $0)).contains("ContextMenu") }) else { return } // 递归遍历修改所有单元格背景 func modifyStyle(in view: UIView) { for subview in view.subviews { if let cell = subview as? UITableViewCell { cell.backgroundColor = .systemBlue cell.contentView.backgroundColor = .systemBlue } modifyStyle(in: subview) } } modifyStyle(in: menuWindow) } }
修改菜单项“Copied”的字体样式
同样分版本适配:
- iOS15+ 官方API实现(无风险)
iOS15开始UIAction新增了attributedTitle属性,支持直接设置富文本样式,修改你的contextMenuConfigurationForRowAt代码如下:
func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { return UIContextMenuConfiguration(identifier: indexPath as NSIndexPath, previewProvider: nil) { _ in let action: UIAction if #available(iOS 15.0, *) { // 构造富文本标题,自定义字体、颜色 var attributes = AttributeContainer() attributes.font = UIFont.boldSystemFont(ofSize: 18) // 替换为你的自定义字体 attributes.foregroundColor = .white let customTitle = AttributedString("Copied", attributes: attributes) action = UIAction(title: "", image: UIImage(named: "copy"), attributes: .disabled) { _ in } action.attributedTitle = customTitle } else { // 低版本降级方案,使用默认样式或者用下面的遍历方案修改 action = UIAction(title: "Copied", image: UIImage(named: "copy"), attributes: .disabled) { _ in } } return UIMenu(title: "", children: [action]) } }
- iOS13/14 兼容实现
在上面提到的willDisplay回调中,遍历找到对应文字的Label修改样式即可,追加modifyStyle方法的逻辑:
func modifyStyle(in view: UIView) { for subview in view.subviews { if let cell = subview as? UITableViewCell { cell.backgroundColor = .systemBlue cell.contentView.backgroundColor = .systemBlue } // 匹配文字修改字体 if let label = subview as? UILabel, label.text == "Copied" { label.font = UIFont.boldSystemFont(ofSize: 18) // 自定义字体 label.textColor = .white // 自定义文字颜色 } modifyStyle(in: subview) } }
注意:低版本适配用到的视图遍历逻辑仅修改公开属性,没有调用私有API,不会被App Store审核拒绝。
内容的提问来源于stack exchange,提问作者tech_human
相关产品推荐
相关产品推荐

