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

iOS键盘建议栏遮挡内容:滚动视图适配问题求助

解决Swift滚动视图避开键盘时未识别建议栏的问题

嘿,我之前做Swift滚动视图适配键盘的时候也踩过这个坑!默认的键盘通知返回的frame是不包含顶部建议栏/候选输入栏的,这就会导致输入框刚好被那部分挡住,特别影响体验。

给你调整一下代码,核心是用包含预测栏的键盘frame键来替代原来的键,同时做一下iOS版本兼容:

修改后的键盘通知监听代码

func registerForKeyboardNotifications() {
    // 注册键盘显示/隐藏的通知
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(keyboardWillShow(_:)),
        name: UIResponder.keyboardWillShowNotification,
        object: nil
    )
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(keyboardWillHide(_:)),
        name: UIResponder.keyboardWillHideNotification,
        object: nil
    )
}

@objc private func keyboardWillShow(_ notification: Notification) {
    guard let userInfo = notification.userInfo else { return }
    
    // 优先获取包含预测栏的键盘完整frame(iOS 11+支持)
    let keyboardFrame: CGRect
    if #available(iOS 11.0, *) {
        keyboardFrame = userInfo[UIKeyboardFrameIncludingPredictiveKeyboardUserInfoKey] as! CGRect
    } else {
        // 低版本用原来的键盘frame
        keyboardFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as! CGRect
    }
    
    // 将键盘的frame转换为滚动视图的坐标系
    let convertedKeyboardFrame = scrollView.convert(keyboardFrame, from: nil)
    // 计算需要预留的底部间距:滚动视图底部到键盘顶部的距离
    let bottomInset = scrollView.frame.maxY - convertedKeyboardFrame.minY
    
    // 设置滚动视图的内容内边距和滚动指示器内边距
    scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: bottomInset, right: 0)
    scrollView.scrollIndicatorInsets = scrollView.contentInset
    
    // 可选:自动滚动到当前活跃的输入框
    if let activeTextField = UIResponder.currentFirstResponder() as? UITextField {
        scrollView.scrollRectToVisible(activeTextField.frame, animated: true)
    }
}

@objc private func keyboardWillHide(_ notification: Notification) {
    // 键盘隐藏时恢复内边距
    scrollView.contentInset = .zero
    scrollView.scrollIndicatorInsets = .zero
}

// 记得在销毁时移除通知,避免内存泄漏
deinit {
    NotificationCenter.default.removeObserver(self)
}

额外优化:自动滚动到输入框

上面代码里加了一个可选的自动滚动逻辑,需要你给UIResponder加一个扩展来获取当前活跃的输入框:

extension UIResponder {
    static func currentFirstResponder() -> UIResponder? {
        _currentFirstResponder = nil
        UIApplication.shared.sendAction(#selector(findFirstResponder(_:)), to: nil, from: nil, for: nil)
        return _currentFirstResponder
    }
    
    private static weak var _currentFirstResponder: UIResponder?
    
    @objc private func findFirstResponder(_ sender: Any) {
        UIResponder._currentFirstResponder = self
    }
}

这样处理后,滚动视图会把键盘的完整高度(包括顶部的建议栏)都计算进去,你的手机号输入框就不会被遮挡了,体验会顺畅很多!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:33:21