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

Swift中点击菜单栏项后如何将其设置为禁用状态?

实现UIMenu中UIAction点击后禁用的方法

当然可以实现,核心思路是通过控制UIAction的isEnabled属性,结合菜单更新逻辑达成效果。以下是两种可行的实现方案:

方案一:直接修改UIAction状态并更新菜单

将需要控制的UIAction定义为类的实例属性,点击后修改其isEnabled,再重新生成菜单赋值给BarButtonItem:

class YourViewController: UIViewController {
    // 将需要控制的操作定义为实例属性
    private lazy var copyAction: UIAction = {
        UIAction(title: NSLocalizedString("Copy", comment: ""), image: UIImage(systemName: "doc.on.doc")) { [weak self] _ in
            // 执行复制逻辑
            self?.performCopy()
            // 禁用当前操作
            self?.copyAction.isEnabled = false
            // 重新生成菜单并更新
            self?.refreshOptionsMenu()
        }
    }()
    
    private lazy var renameAction: UIAction = {
        UIAction(title: NSLocalizedString("Rename", comment: ""), image: UIImage(systemName: "pencil"), handler: self.handleOtherActions)
    }()
    
    private lazy var duplicateAction: UIAction = {
        UIAction(title: NSLocalizedString("Duplicate", comment: ""), image: UIImage(systemName: "plus.square.on.square"), handler: self.handleOtherActions)
    }()
    
    private lazy var moveAction: UIAction = {
        UIAction(title: NSLocalizedString("Move", comment: ""), image: UIImage(systemName: "folder"), handler: self.handleOtherActions)
    }()
    
    private var optionsBarItem: UIBarButtonItem!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupBarButton()
    }
    
    private func setupBarButton() {
        optionsBarItem = UIBarButtonItem(title: "选项", style: .plain, target: nil, action: nil)
        refreshOptionsMenu()
        navigationItem.rightBarButtonItem = optionsBarItem
    }
    
    private func refreshOptionsMenu() {
        let menu = UIMenu(title: "", children: [copyAction, renameAction, duplicateAction, moveAction])
        optionsBarItem.menu = menu
    }
    
    private func performCopy() {
        // 这里写入你的复制业务逻辑
        print("执行复制操作")
    }
    
    private func handleOtherActions(action: UIAction) {
        // 处理其他菜单操作的逻辑
        print("执行\(action.title)操作")
    }
}

说明

  • 因为UIMenu是不可变对象,修改UIAction的属性后必须重新生成菜单并赋值,才能让界面更新。
  • 禁用后的UIAction会自动变为灰色,无法被点击。

方案二:动态生成菜单(iOS 15+)

利用UIMenu的provider参数,每次打开菜单时动态生成子项,根据状态决定是否禁用目标操作:

class YourViewController: UIViewController {
    // 用变量记录操作的启用状态
    private var isCopyEnabled = true
    private var optionsBarItem: UIBarButtonItem!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupBarButton()
    }
    
    private func setupBarButton() {
        optionsBarItem = UIBarButtonItem(title: "选项", style: .plain, target: nil, action: nil)
        // 使用provider闭包动态生成菜单
        optionsBarItem.menu = UIMenu(title: "", children: []) { [weak self] _ in
            guard let self = self else { return UIMenu(title: "", children: []) }
            return UIMenu(title: "", children: self.generateMenuActions())
        }
        navigationItem.rightBarButtonItem = optionsBarItem
    }
    
    private func generateMenuActions() -> [UIAction] {
        let copyAction = UIAction(title: NSLocalizedString("Copy", comment: ""), image: UIImage(systemName: "doc.on.doc"), isEnabled: isCopyEnabled) { [weak self] _ in
            self?.performCopy()
            // 更新禁用状态
            self?.isCopyEnabled = false
        }
        
        let renameAction = UIAction(title: NSLocalizedString("Rename", comment: ""), image: UIImage(systemName: "pencil"), handler: self.handleOtherActions)
        let duplicateAction = UIAction(title: NSLocalizedString("Duplicate", comment: ""), image: UIImage(systemName: "plus.square.on.square"), handler: self.handleOtherActions)
        let moveAction = UIAction(title: NSLocalizedString("Move", comment: ""), image: UIImage(systemName: "folder"), handler: self.handleOtherActions)
        
        return [copyAction, renameAction, duplicateAction, moveAction]
    }
    
    private func performCopy() {
        print("执行复制操作")
    }
    
    private func handleOtherActions(action: UIAction) {
        print("执行\(action.title)操作")
    }
}

说明

  • 每次打开菜单时,系统会调用provider闭包生成最新的菜单内容,无需手动更新菜单。
  • 适合需要根据多个状态动态调整菜单的复杂场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:09:13