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

iOS中如何动态更新UIMenu与UIContextMenuConfiguration?

实现UITableView单元格菜单的动态更新

由于UIMenu是不可变类型,无法直接修改已创建菜单的内容,核心解决思路是每次菜单显示时,根据当前数据状态动态生成新的UIMenu和UIAction实例,而非复用旧实例。以下针对两种常见场景给出具体实现:

场景1:使用UIContextMenuConfiguration(上下文菜单)

通过UITableView的代理方法contextMenuConfigurationForRowAt生成菜单配置,其中的actionProvider闭包会在每次菜单即将显示时被调用,正好用来动态生成对应状态的操作:

// 假设用这个数组记录每行的收藏状态,需提前初始化并与数据源对应
var favoriteStates: [Bool] = []

func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
    return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [weak self] suggestedActions in
        guard let self = self else { return nil }
        // 获取当前行的收藏状态
        let isFavorite = self.favoriteStates[indexPath.row]
        // 根据状态生成对应的操作标题和图标
        let actionTitle = isFavorite ? "Remove from Favourites" : "Add to Favourites"
        let actionImage = isFavorite ? UIImage(systemName: "heart.fill") : UIImage(systemName: "heart")
        
        let favoriteAction = UIAction(title: actionTitle, image: actionImage) { _ in
            // 切换收藏状态
            self.favoriteStates[indexPath.row].toggle()
            // 刷新当前行,确保下次菜单状态正确
            tableView.reloadRows(at: [indexPath], with: .automatic)
        }
        
        // 返回新创建的菜单
        return UIMenu(title: "", children: [favoriteAction])
    }
}

场景2:直接设置UITableViewCell的menu属性

如果是通过单元格的menu属性绑定菜单(iOS 14+支持),需在单元格即将显示时,根据当前状态重新生成并设置菜单:

var favoriteStates: [Bool] = []

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    let isFavorite = favoriteStates[indexPath.row]
    let actionTitle = isFavorite ? "Remove from Favourites" : "Add to Favourites"
    let actionImage = isFavorite ? UIImage(systemName: "heart.fill") : UIImage(systemName: "heart")
    
    let favoriteAction = UIAction(title: actionTitle, image: actionImage) { [weak self] _ in
        guard let self = self else { return }
        self.favoriteStates[indexPath.row].toggle()
        tableView.reloadRows(at: [indexPath], with: .automatic)
    }
    
    // 给单元格设置新的菜单实例
    cell.menu = UIMenu(title: "", children: [favoriteAction])
}

关键注意点

  • 每次菜单显示前都要重新创建UIMenu和UIAction,利用不可变类型的特性,用新实例替代旧实例。
  • 切换收藏状态后,必须刷新对应行(reloadRows),确保后续菜单生成时能获取最新状态。

内容的提问来源于stack exchange,提问作者Kris2k

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:20:56