I noticed this too while having trouble with NSToolbarItem
actions and after investigating with Hopper I figured out the reason is although UIWindow
's nextResponder
is UIWindowScene
, it does not have a nextResponder
override that forwards to its delegate (our SceneDelegate
class that conforms to UIWindowSceneDelegate
), it's superclass - UIScene
's next is the UIApplication
which has next the app delegate.
My guess is requiring a scene delegate conforming class to have as next responder the application syntactically is tricky, and even if it is achieved in ObjC it is likely even harder or impossible in Swift. Maybe Apple just decided it wasn't worth the hassle. With Catalyst, any NSToolbarItem
for the window scene's toolbar can just have their target set to self - the scene delegate, rather than search the responder chain, even the system items can have their target changed during toolbarWillAddItem
like in the sample. It would have been nice if they had at least documented somewhere a warning that the window scene delegate isn't in the responder chain, especially because as you say it is a subclass of UIResponder
.
If you would like it to be in the chain then I created a workaround (see code below). First create a subclass of UIWindowScene
with a nextResponder
method returning self.delegate
. Second, in the scene delegate add a nextResponder
that returns UIApplication.sharedApplication
(which will forward to the app delegate). Finally in the Scene Manifest (in Info.plist
) add a row under the default configuration and choose Class Name from the drop down and enter your subclass's name.
I suppose this could be useful for an action that needs access to the window, because once an action reaches the app delegate it is harder to figure out which scene window it came from. However as I said, in this case what is the point in searching the chain at all.
MyWindowScene.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface MyWindowScene : UIWindowScene
@end
NS_ASSUME_NONNULL_END
MyWindowScene.m
#import "MyWindowScene.h"
@implementation MyWindowScene
- (UIResponder *)nextResponder{
return self.delegate;
}
@end
SceneDelegate.m
@implementation SceneDelegate
...
- (UIResponder *)nextResponder{
return UIApplication.sharedApplication;
}
