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).