Solution 1:

You need to do three things:

  1. You need to call -becomeFirstResponder on the view or view controller.
  2. Your view or view controller needs to implement -canBecomeFirstResponder (returning YES).
  3. Optionally, your view or view controller can implement -canPerformAction:action withSender:sender to show/hide menu items on an individual basis.

Solution 2:

The answer mentions three things, but to be picky, there are six:

  1. The menu handler must be a UIView. If it isn't, -becomeFirstResponder fails.
  2. The menu handler must have userInteractionEnabled = YES
  3. The menu handler must be in the view hierarchy and its -window property must be the same as the window for the view in the inView: argument.
  4. You need to implement -canBecomeFirstResponder and return YES.
  5. You need to call [handler becomeFirstResponder], before [menu setTargetRect:inView:] is called, or the latter will fail.
  6. You need to call [menu setTargetRect:inView] (at least once) and [menu setMenuVisible:animated:].

In particular points 1-3 above got me. I wanted a custom menu handler class that was a UIResponder at first, which caused -becomeFirstResponder to return NO; then it was a UIView, which failed, then I tried making it a UIButton which worked, but only because userInteractionEnabled defaults to YES for buttons and NO for UIViews.