iOS 18 beta REGRESSION: UIDocumentViewController is no longer in responder chain for title menu item actions?

In testing my app with the WWDC24 iOS 18 beta, I have noticed that most of the menu items in the navigation bar and title menu are either missing, disabled, or nonfunctional.

The structure of my app's UI is a UIDocumentController subclass as the root view controller of a UINavigationController.

In debugging the problem with title menu items, I noticed that the responder chain from the UICommand.sender now starts at the UINavigationBar and goes up from there, without passing through the UIDocumentViewController itself. Now, only the actions I've defined in the AppDelegate are accessible.

I'm not exactly sure how this was organized on iOS 17, but the responder chain did include the UIDocumentViewController, where I have implemented most of the menu item actions.

This seems like a UIKit bug, but I am investigating possible workarounds in case Apple does not fix it. Suggestions welcome.

Hi,

there is no change in expected behavior here in iOS 18. I would be curious to see your app setup. Would you mind filing this through the feedback assistant with a sample app and then responding back with the feedback number?

—Michael

I don't think I'll have time to create a sample app to demonstrate the problem, but I have requested a couple UIKit consultations (still listed as Pending) to discuss this and other issues via WebEx.

I was recently able to work around the problem as follows:

  • Configured the UINavigationController in the Main Storyboard to use a custom UINavigationBar subclass, which contains the following methods (and nothing else):
- (UINavigationController *)myNavigationController {
    UIResponder * next = super.nextResponder;

    // perhaps needlessly complex; I expect next == UINavigationController at this point

    while ( next && ![next isKindOfClass:UINavigationController.class] ) {
        next = next.nextResponder;
    }

    return (UINavigationController *)next;
}

- (UIResponder *)nextResponder {
    UIResponder * responder = [self myNavigationController].topViewController ?: [super nextResponder];

    return responder;
}

This change got my UIDocumentViewController back into the responder chain, but I found that there was another problem:

I had an override of -canPerformAction:withSender: in my UIDocumentViewController subclass in order to work around the problem described in https://developer.apple.com/forums/thread/724027> (FB13258087):

// FIXME: working around FB13258087 <https://developer.apple.com/forums/thread/724027>
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    BOOL canDoIt = [super canPerformAction:action withSender:sender];
   ...
}

During debug I found that under iOS 18, canDoIt was evaluating to NO for actions implemented by my UIDocumentViewController subclass, such as duplicate: and print:. It seems that the superclass method was not providing the default behavior as described in the API documentation ("This default implementation of this method returns YES if the responder class implements the requested action and calls the next responder if it doesn’t.").

  • I changed the implementation of my method override to directly implement the default behavior:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    BOOL canDoIt = [self respondsToSelector:action] ?: [self.nextResponder canPerformAction:action withSender:sender]; // *** calling super was returning NO in iOS 18 for implemented methods like duplicate: and print:

With these two changes, I'm seeing the expected behavior (same as in iOS 17.5) as far as navigation bar menu items are concerned (I have other iOS 18-related regressions to investigate, separate from this).

I looked into this. The only workaround you should need is to implement canPerformAction:withSender: on your UIDocumentViewController subclass as follows:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    return [super canPerformAction:action withSender:sender] || action == <yourCustomSelector>;
}

To be clear though, this is a bug and is expected to work like it did in iOS 17.

Thanks for looking into this!

So, just to check my understanding, it sounds like this is a bug in the developer beta, which should be fixed before GM. So I'll need the workaround shown above for now, but should be able to remove it post-beta.

Problem remains in iOS 18.0 beta 2 (22A5297f). No change.

I had hoped this would be fixed in the second beta or at least before the first public beta, since it completely breaks my app.

iOS 18 beta REGRESSION: UIDocumentViewController is no longer in responder chain for title menu item actions?
 
 
Q