我在 iOS / 中遇到了这个问题UIWebView
,它没有makeFirstResponder
在UIWindow
,webViewDidEndEditing
或中实现shouldBeginEditingInDOMRange
。然而,通过使用 Swizzling,我能够创建一个帮助类别,允许检索当前的第一响应者,并在每次第一响应者更改时发布通知。真的令人沮丧,这一切应该是公共 API,但不是,因为 swizzle 通常不是第一个 goto,但这已经足够好了。
首先,设置您的类别标题:
@interface UIResponder (Swizzle)
+ (UIResponder *)currentFirstResponder;
- (BOOL)customBecomeFirstResponder;
@end
然后分类实现
@implementation UIResponder (Swizzle)
// It's insanity that there is no better way to get a notification when the first responder changes, but there it is.
static UIResponder *sCurrentFirstResponder;
+ (UIResponder *)currentFirstResponder {
return sCurrentFirstResponder;
}
- (BOOL)customBecomeFirstResponder {
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity:2];
if(sCurrentFirstResponder) {
[userInfo setObject:sCurrentFirstResponder forKey:NSKeyValueChangeOldKey];
}
sCurrentFirstResponder = self;
if(sCurrentFirstResponder) {
[userInfo setObject:sCurrentFirstResponder forKey:NSKeyValueChangeNewKey];
}
[[NSNotificationCenter defaultCenter] postNotificationName:kFirstResponderDidChangeNotification
object:nil
userInfo:userInfo];
return [self customBecomeFirstResponder];
}
@end
最后,使用JR Swizzle之类的助手,交换类。
#import "JRSwizzle.h"
- (void)applicationLoaded {
if(![UIResponder jr_swizzleMethod:@selector(becomeFirstResponder) withMethod:@selector(customBecomeFirstResponder) error:&error]) {
NSLog(@"Error swizzling - %@",error);
}
}
以为我会分享。在 App Store 中有效,因为它不使用私有 API,虽然 Apple 警告不要混合基类,但没有禁止这样做的法令。