Swift中点击菜单栏项后如何将其设置为禁用状态?
当然可以实现,核心思路是通过控制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
相关产品推荐
相关产品推荐

