You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需TextField实例全局获取键盘顶部的ToolBar/InputAccessoryView?

全局修复IQKeyboardManager空工具栏按钮的无障碍问题

核心思路

通过全局监听键盘弹出/输入框激活的通知,定位IQKeyboardManager为输入框添加的顶部工具栏,过滤并移除其中的空标题按钮,解决无障碍模式下读出“Dimmed button”的问题。

实现步骤

  1. 注册全局通知监听
    在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];
  1. 定位并修复工具栏
    实现通知回调方法,找到当前活跃的输入框(第一响应者),获取其关联的工具栏并过滤空按钮:
- (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;
}
  1. 清理监听(避免内存泄漏)
    在AppDelegate的dealloc方法中移除通知监听:
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

注意事项

  • 该方案不依赖IQKeyboardManager私有API,兼容性更强,即使Pod版本更新,只要工具栏仍通过inputAccessoryView绑定,就能正常工作。
  • 若IQKeyboardManager调整工具栏生成逻辑,可根据实际情况修改过滤条件(比如通过按钮tag或其他属性识别空按钮)。

内容的提问来源于stack exchange,提问作者Shajo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:10:17