Get the current first responder without using a private API

前端 未结 28 1806
夕颜
夕颜 2020-11-22 05:03

I submitted my app a little over a week ago and got the dreaded rejection email today. It tells me that my app cannot be accepted because I\'m using a non-public API; specif

28条回答
  •  情深已故
    2020-11-22 05:45

    Here's a solution which reports the correct first responder (many other solutions won't report a UIViewController as the first responder, for example), doesn't require looping over the view hierarchy, and doesn't use private APIs.

    It leverages Apple's method sendAction:to:from:forEvent:, which already knows how to access the first responder.

    We just need to tweak it in 2 ways:

    • Extend UIResponder so it can execute our own code on the first responder.
    • Subclass UIEvent in order to return the first responder.

    Here is the code:

    @interface ABCFirstResponderEvent : UIEvent
    @property (nonatomic, strong) UIResponder *firstResponder;
    @end
    
    @implementation ABCFirstResponderEvent
    @end
    
    @implementation UIResponder (ABCFirstResponder)
    - (void)abc_findFirstResponder:(id)sender event:(ABCFirstResponderEvent *)event {
        event.firstResponder = self;
    }
    @end
    
    @implementation ViewController
    
    + (UIResponder *)firstResponder {
        ABCFirstResponderEvent *event = [ABCFirstResponderEvent new];
        [[UIApplication sharedApplication] sendAction:@selector(abc_findFirstResponder:event:) to:nil from:nil forEvent:event];
        return event.firstResponder;
    }
    
    @end
    

提交回复
热议问题