Вот решение, в котором сообщается о правильном первом ответчике (многие другие решения, например, не сообщают об UIViewController
в качестве первого ответчика), не требует циклизации по иерархии представлений и не использует частные API .
Он использует метод Apple sendAction: to: from: forEvent: , который уже знает, как получить доступ к первому ответчику.
Нам просто нужно настроить это двумя способами:
UIResponder
, чтобы он мог выполнить наш собственный код для первого ответчика. UIEvent
, чтобы вернуть первого ответчика. Вот код:
@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