4

As iOS14 offers an easy way to setup the menu on the UIBarButtonItem, I wonder do I miss that there is no easy way to setup its items as they may depend on the current context.

I see that there is UIDeferredMenuElement, but this doesn't seem to be a good use case for it?

Also I see that there is primaryAction, but there doesn't seem to be a trivial way to call the menu from there.

And the third option seems to be reshuffling the menu on each change that may affect it, but that doesn't seem like a great idea.

I assume that there is something I miss out.

Ivan Ičin
  • 9,672
  • 5
  • 36
  • 57

2 Answers2

2

Basically for a simple bar button item there's no such provision. A UIControl like a UIButton has an event .menuActionTriggered, and it is perfectly reasonable, at that moment, to construct and assign the menu to the control, thus implementing a dynamic menu that is constructed just in the instant before the menu appears.

But you can't do that with a bar button item — unless it is a custom view bar button item with a UIButton in it.

What you'd have to do otherwise is watch the surrounding conditions via some other mechanism and just change the bar button item's menu each time the conditions change. It sounds like a pain in the butt but it's probably your only option. (I take it that that's exactly what you mean when you say "And the third option seems to be reshuffling the menu on each change that may affect it, but that doesn't seem like a great idea.")

I think what you're asking for is reasonable and it seems sort of silly that there's no provision for it; if you have a good use case, I'd recommend filing an enhancement request with Apple.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • thanks. There are other issues like that context in my app may change after the user presses the button so it has to be captured at that moment. I guess the only solution would be that custom view. – Ivan Ičin Aug 19 '20 at 17:28
0

Here is the Swift 5 version of implementation, inspired by @matt 's answer.

private func setButton() {
    button.menu = UIMenu() // Here must be a placeholder menu. As the menu won't show if button.menu is nil.
    button.showsMenuAsPrimaryAction = true
    button.addTarget(self, action: #selector(createMenu(_:)), for: .menuActionTriggered)
}

@objc private func createMenu(_ button:UIButton) {
    ...
}

This is the only solution so far. As func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) doesn't called every time unless you hold for a while when a button is set to showsMenuAsPrimaryAction = true.

----edited----

If my answer was correct, so matt's. As my code was based on his idea. So I didn't think that matt was wrong at the first place. I just thought that the questioner had misunstanding with matt's answer.

Owen Zhao
  • 3,205
  • 1
  • 26
  • 43
  • At first I downvoted as Matt's answer was basically that there is no answer except to change the menu before the action. So your answer may even be correct, but it surely needs better description. To confirm does it show the menu customized at the moment of the user tap on the button? Also I can't pull my downvote unless you edit the answer as the site doesn't allow it. – Ivan Ičin Apr 29 '21 at 11:30
  • you provided a wrong explanation as cited above. I’ve tried to explain why I downvoted (it came with a reason) and why I can’t technically change my downvote, if you feel like complaining on that it is not sensible. – Ivan Ičin May 02 '21 at 14:37
  • But I did accept your answer, just I can’t upvote unless you edit it. And I certainly suggest you to remove references to Matt’s answer as it tells something different. – Ivan Ičin May 02 '21 at 14:45
  • I didn't think matt's wrong. I thought you misunderstood. – Owen Zhao May 02 '21 at 14:59
  • Whatever. If you are correct then he is wrong because he said it is impossible and it needs to be submitted to Apple as a request for improvement. So either you are wrong or he is. – Ivan Ičin May 02 '21 at 15:16
  • I apologize this is the wrong answer as you clearly miss that I was talking about UIBarButtonItem so your answer doesn't address it. – Ivan Ičin May 12 '21 at 14:33