为何点击ContextMenu选项后UIBarButtonItem的图标会变更?
问题原因
这是因为你创建UIMenu时设置了.singleSelection选项——这是UIKit针对单选菜单的默认行为:当用户选中菜单里的某个UIAction时,系统会自动将该UIAction的图标替换为父控件UIBarButtonItem的当前图标,以此直观反馈用户的单选选择状态。
解决方案
根据你的需求,有两种处理方式:
1. 移除单选选项(无需单选功能时)
直接去掉UIMenu的.singleSelection选项,菜单就不会触发图标替换行为:
func makeUIMenu() -> UIMenu { guard let emptyFolder, let importFile, let importPhotoOrVideo else { return UIMenu() } return UIMenu(title: "Add", image: .folder.applyingSymbolConfiguration(.symbolConfig), options: [.displayInline], // 移除.singleSelection children: [importPhotoOrVideo, importFile, emptyFolder]) }
2. 保留单选但手动控制图标(需要单选功能时)
如果要保留单选逻辑,但不想替换UIBarButtonItem的图标,可以手动管理UIAction的选中状态,并在每次操作后重置图标:
private init() { emptyFolder = UIAction( title: "Empty Folder", image: .folderBadgePlus.applyingSymbolConfiguration(.symbolConfig), identifier: nil, state: .off, handler: { action in // 取消其他选项的选中状态 self.importFile?.state = .off self.importPhotoOrVideo?.state = .off // 切换当前选项状态 action.state = .on // 重置UIBarButtonItem图标 (self.delegate as? ViewController)?.fooItem.image = .folder.applyingSymbolConfiguration(.symbolConfig) self.delegate?.didTappedEmptyFolder() } ) importFile = UIAction( title: "Import File", image: .squareAndArrowDown.applyingSymbolConfiguration(.symbolConfig), identifier: nil, state: .off, handler: { action in self.emptyFolder?.state = .off self.importPhotoOrVideo?.state = .off action.state = .on (self.delegate as? ViewController)?.fooItem.image = .folder.applyingSymbolConfiguration(.symbolConfig) self.delegate?.didTappedImportFile() } ) importPhotoOrVideo = UIAction( title: "Import Photo & Video", image: .photo.applyingSymbolConfiguration(.symbolConfig), identifier: nil, state: .off, handler: { action in self.emptyFolder?.state = .off self.importFile?.state = .off action.state = .on (self.delegate as? ViewController)?.fooItem.image = .folder.applyingSymbolConfiguration(.symbolConfig) self.delegate?.didTappedImportFile() } ) } // 移除UIMenu的.singleSelection选项 func makeUIMenu() -> UIMenu { guard let emptyFolder, let importFile, let importPhotoOrVideo else { return UIMenu() } return UIMenu(title: "Add", image: .folder.applyingSymbolConfiguration(.symbolConfig), options: [.displayInline], children: [importPhotoOrVideo, importFile, emptyFolder]) }
内容的提问来源于stack exchange,提问作者Ufuk Köşker
相关产品推荐
相关产品推荐

