How do I add the UIApplicationDelegate to the end

2019-04-08 11:00发布

问题:

I'm trying to provide an IBAction method for common functionality that is required at various parts of the app.

i.e. Login is implemented modally, and if it succeeds results in a notification that allows all loaded view controllers to react to this event (transition from anonymous to authenticated)

@interface MyAppDelegate : NSObject <UIApplicationDelegate>
{
  ...
}
- (IBAction)loginTapped:(id)sender;
@end

I set the action of that button to the First Responder in IB, however the responder chain doesn't give MyAppDelegate a chance to respond.

My problem is that, I don't want to replicate the method at various parts of the responder chain, I would like to add it to a common class that is already a subclass.

The UIResponder chain goes all the way through to the UIApplication but that seems to be the end. My UIApplicationDelegate doesn't get to participate.

I want to insert or add my app delegate to the responder chain!

(or find another way to hook up the UIButton touch-up-inside to an app-wide implementation.. I want to avoid subclassing the UITabBarController or UIWindow if possible)

回答1:

You could subclass UIApplication to have -nextResponder return the application delegate if it is a UIResponder subclass. You'll then need to alter your call to UIApplicationMain to use your custom subclass.

I haven't tried this myself, but I can't think of any immediate problems this would cause.



回答2:

Starting with iOS 5, the AppDelegate is automatically the last link in the responder chain. Xcode project templates will create an AppDelegate that is a subclass of UIResponder rather than NSObject. However, to avoid cluttering up the AppDelegate, override the AppDelegate's nextResponder and offload work into a custom UIResponder object:

- (UIResponder *)nextResponder
{
    static dispatch_once_t onceToken;
    static LastUIResponder *lastResponder = nil;
    dispatch_once(&onceToken, ^{
        lastResponder = [[LastUIResponder alloc] init];
    });
    return lastResponder;
}