ContextMenu issue in UIBarButtonItem

254 Views Asked by At

I put UIBarButtonItem inside Toolbar as you can see in Storyboard. I put UIMenu in UIBarButtonItem.menu. When I click a button in UIMenu, the icon of the button I clicked is transferred to UIBarButtonItem. Why is this happening?

Question:

Why does the UIBarButtonItem's icon change when I press the button from ContextMenu?

Video:

enter image description here

Storyboard:

enter image description here

UIBarButtonItem Attributes:

enter image description here

ViewController:

@IBOutlet weak var fooItem: UIBarButtonItem!

//MARK: Functions
override func viewDidLoad() {
    super.viewDidLoad()
    fooItem.menu = ContextMenuManager.shared.makeUIMenu()
}

ContextMenuManager:

protocol ContextMenuFunctionable {
    func didTappedEmptyFolder()
    func didTappedImportFile()
}

class ContextMenuManager {
    
    static var shared = ContextMenuManager()
    
    var delegate: ContextMenuFunctionable?
    var emptyFolder: UIAction?
    var importFile: UIAction?
    var importPhotoOrVideo: UIAction?
    
    private init() {
        
        emptyFolder = UIAction(
            title: "Empty Folder",
            image: .folderBadgePlus
                .applyingSymbolConfiguration(.symbolConfig),
            identifier: nil,
            state: .off,
            handler: { _ in self.delegate?.didTappedEmptyFolder() }
        )
        
        importFile = UIAction(
            title: "Import File",
            image: .squareAndArrowDown.applyingSymbolConfiguration(.symbolConfig),
            identifier: nil,
            state: .off,
            handler: { _ in self.delegate?.didTappedImportFile() }
        )
        
        importPhotoOrVideo = UIAction(
            title: "Import Photo & Video",
            image: .photo.applyingSymbolConfiguration(.symbolConfig),
            identifier: nil,
            state: .off,
            handler: { _ in self.delegate?.didTappedImportFile() }
        )
    }

    
    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])
    }
}
1

There are 1 best solutions below

0
HangarRash On

Uncheck the "Selection as Primary Action" checkbox and the button's icon should no longer change when you make a menu selection.

I replicated what you are seeing in code. I created a menu basically using your ContextMenuManager code but I created the UIBarButtonItem as follows:

let menu = UIMenu(title: "Add",
                  options: [.displayInline, .singleSelection],
                  children: [importPhotoOrVideo, importFile, emptyFolder])

let button = UIBarButtonItem(image: UIImage(systemName: "doc.on.clipboard.fill"), menu: menu)
button.changesSelectionAsPrimaryAction = false

When changesSelectionAsPrimaryAction is set to true, the button's icon reflects the chosen menu. When set to false, it retains its own icon.