如何无需TextField实例全局获取键盘顶部的ToolBar/InputAccessoryView?
全局修复IQKeyboardManager空工具栏按钮的无障碍问题
核心思路
通过全局监听键盘弹出/输入框激活的通知,定位IQKeyboardManager为输入框添加的顶部工具栏,过滤并移除其中的空标题按钮,解决无障碍模式下读出“Dimmed button”的问题。
实现步骤
- 注册全局通知监听
在AppDelegate的application:didFinishLaunchingWithOptions:方法中添加通知监听,确保能全局捕获工具栏出现的时机:
// 监听键盘弹出通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fixEmptyToolbarButton:) name:UIKeyboardWillShowNotification object:nil]; // 监听输入框激活通知,更及时捕获工具栏 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fixEmptyToolbarButton:) name:UITextFieldTextDidBeginEditingNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fixEmptyToolbarButton:) name:UITextViewTextDidBeginEditingNotification object:nil];
- 定位并修复工具栏
实现通知回调方法,找到当前活跃的输入框(第一响应者),获取其关联的工具栏并过滤空按钮:
- (void)fixEmptyToolbarButton:(NSNotification *)notification { UIResponder *firstResponder = [self getCurrentFirstResponder]; if (!firstResponder) return; // 确认是IQKeyboardManager生成的UIToolbar UIToolbar *keyboardToolbar = (UIToolbar *)firstResponder.inputAccessoryView; if (![keyboardToolbar isKindOfClass:[UIToolbar class]] || keyboardToolbar.items.count == 0) return; // 过滤无标题的普通样式按钮(对应源码中添加的空标题按钮) NSMutableArray *validItems = [NSMutableArray array]; for (UIBarButtonItem *item in keyboardToolbar.items) { if (!(item.title.length == 0 && item.style == UIBarButtonItemStylePlain)) { [validItems addObject:item]; } } // 仅当内容有变化时更新工具栏 if (validItems.count != keyboardToolbar.items.count) { keyboardToolbar.items = validItems; } } // 递归查找当前窗口的第一响应者 - (UIResponder *)getCurrentFirstResponder { UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; return [self findFirstResponderInView:keyWindow]; } - (UIResponder *)findFirstResponderInView:(UIView *)view { for (UIView *subview in view.subviews) { if (subview.isFirstResponder) { return subview; } UIResponder *responder = [self findFirstResponderInView:subview]; if (responder) { return responder; } } return nil; }
- 清理监听(避免内存泄漏)
在AppDelegate的dealloc方法中移除通知监听:
- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
注意事项
- 该方案不依赖IQKeyboardManager私有API,兼容性更强,即使Pod版本更新,只要工具栏仍通过
inputAccessoryView绑定,就能正常工作。 - 若IQKeyboardManager调整工具栏生成逻辑,可根据实际情况修改过滤条件(比如通过按钮
tag或其他属性识别空按钮)。
内容的提问来源于stack exchange,提问作者Shajo
相关产品推荐
相关产品推荐

