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

iOS开发:如何在系统键盘上方添加视图并在Globe与Mic按钮间插入分段控件

iOS开发:如何在系统键盘上方添加视图并在Globe与Mic按钮间插入分段控件

嘿,这个需求我之前帮朋友折腾过,其实核心就是要抓住系统键盘的视图结构,再结合自定义输入视图的特性来处理,下面给你一步步拆解:

  • 第一步:监听键盘弹出事件,找到系统键盘的容器
    系统键盘弹出时,我们才能拿到它的视图实例。所以首先要注册键盘显示的通知,在控制器的viewDidLoad里加这段代码:

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow(_:)), name: UIKeyboardDidShowNotification, object: nil)
    

    记得在控制器销毁时移除监听,避免内存泄漏:

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
  • 第二步:定位键盘的顶部工具栏(就是放Globe和Mic的那一行)
    实现keyboardDidShow方法,遍历窗口的子视图找到键盘的容器(通常类名带UIPeripheralHostView),再从里面找到顶部的工具栏(高度比键盘主体小很多):

    @objc private func keyboardDidShow(_ notification: Notification) {
        guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { return }
        // 找到键盘的根容器视图
        let keyboardHostView = keyWindow.subviews.first(where: {
            String(describing: type(of: $0)).contains("UIPeripheralHostView")
        })
        guard let keyboardHost = keyboardHostView else { return }
        // 定位到顶部的工具栏(Globe和Mic所在的行)
        let topToolbar = keyboardHost.subviews.first(where: { $0.frame.height < 50 })
        guard let toolbar = topToolbar else { return }
        
        // 接下来在这里插入分段控件
    }
    
  • 第三步:创建分段控件,插入到Globe和Mic之间
    先初始化我们的分段控件,然后遍历工具栏的子视图找到Globe和Mic按钮,用AutoLayout把分段控件夹在中间:

    // 初始化分段控件
    let segmentControl = UISegmentedControl(items: ["大写", "小写"])
    segmentControl.selectedSegmentIndex = 0
    segmentControl.addTarget(self, action: #selector(segmentValueChanged(_:)), for: .valueChanged)
    toolbar.addSubview(segmentControl)
    segmentControl.translatesAutoresizingMaskIntoConstraints = false
    
    // 找到Globe和Mic按钮(通过accessibilityLabel判断更稳妥)
    let globeButton = toolbar.subviews.first(where: { $0.accessibilityLabel == "Globe" })
    let micButton = toolbar.subviews.first(where: { $0.accessibilityLabel == "Microphone" })
    
    // 布局约束,把分段控件放在两者之间
    if let globeBtn = globeButton, let micBtn = micButton {
        NSLayoutConstraint.activate([
            segmentControl.centerYAnchor.constraint(equalTo: toolbar.centerYAnchor),
            segmentControl.leadingAnchor.constraint(equalTo: globeBtn.trailingAnchor, constant: 8),
            micBtn.leadingAnchor.constraint(equalTo: segmentControl.trailingAnchor, constant: 8)
        ])
    }
    

    这里要注意:不同iOS版本的键盘视图结构可能有小变化,所以如果找不到这两个按钮,可以退而求其次,把分段控件放在工具栏的右侧(Mic左边固定位置),保证兼容性。

  • 第四步:处理自定义inputView的情况
    当你给UITextView设置了自定义inputView时,系统键盘不会弹出,这时候我们的分段控件要通过inputAccessoryView来显示。你可以封装一个通用的工具类,或者直接给UITextView设置:

    // 给自定义输入视图绑定附属视图
    let customInputView = YourCustomKeyboardView()
    textView.inputView = customInputView
    
    // 创建包含分段控件的附属视图
    let accessoryToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
    let segmentControl = UISegmentedControl(items: ["选项1", "选项2"])
    accessoryToolbar.items = [UIBarButtonItem(customView: segmentControl)]
    textView.inputAccessoryView = accessoryToolbar
    

    这样当自定义键盘弹出时,分段控件就会显示在它的上方,和系统键盘的效果保持一致。

  • 额外注意事项

    1. 每次键盘弹出时要检查是否已经添加过分段控件,避免重复添加;
    2. 因为我们操作了系统私有视图(比如UIPeripheralHostView),要多做几个iOS版本的兼容性测试,避免在新系统上失效;
    3. 如果不需要兼容太老的系统,也可以考虑用UIInputViewController来管理自定义输入视图,它的inputAccessoryView会自动和系统键盘联动。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 13:52:59