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

iPhone X中UITextView作为inputAccessoryView的键盘适配问题

解决iPhone X上InputAccessoryView与键盘底部行显示异常的问题

这个问题我之前做类似Messages的聊天界面时也踩过坑,根源其实是iPhone X这类全面屏设备的安全区域(Safe Area)布局差异——底部的Home Indicator区域会干扰键盘和inputAccessoryView的对齐计算,导致键盘底部的功能行(比如数字键、空格、回车)要么错位要么被遮挡。

下面是经过验证的解决方案,一步步来:

1. 用Auto Layout构建自定义InputAccessoryView

别再用frame硬写布局了,改用Auto Layout并绑定到安全区域,让系统能正确计算视图尺寸:

class ChatInputAccessoryView: UIView {
    let messageTextView = UITextView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
        setupConstraints()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupUI()
        setupConstraints()
    }
    
    private func setupUI() {
        backgroundColor = .systemBackground
        messageTextView.font = .systemFont(ofSize: 16)
        messageTextView.textContainerInset = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
        addSubview(messageTextView)
        // 禁用自动转换,强制使用Auto Layout
        translatesAutoresizingMaskIntoConstraints = false
    }
    
    private func setupConstraints() {
        NSLayoutConstraint.activate([
            // 文本框与父视图的边距
            messageTextView.topAnchor.constraint(equalTo: topAnchor, constant: 8),
            messageTextView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
            messageTextView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
            // 关键:绑定到安全区域底部,适配Home Indicator
            messageTextView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -8),
            // 确保输入栏有最小高度,避免被压缩
            heightAnchor.constraint(greaterThanOrEqualToConstant: 44)
        ])
    }
    
    // 重写固有内容尺寸,让系统自动计算高度
    override var intrinsicContentSize: CGSize {
        return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
    }
}

2. 正确配置视图控制器的InputAccessoryView

确保视图控制器正确返回自定义输入栏,并且允许成为第一响应者:

class ChatViewController: UIViewController {
    private let inputAccessoryView = ChatInputAccessoryView()
    
    override var inputAccessoryView: UIView? {
        return inputAccessoryView
    }
    
    override var canBecomeFirstResponder: Bool {
        return true
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 禁用自动调整滚动视图内边距(如果页面有滚动视图的话),避免布局冲突
        automaticallyAdjustsScrollViewInsets = false
    }
}

3. 键盘通知辅助修正布局(可选但推荐)

如果还是偶尔出现显示异常,可以监听键盘弹出通知,手动修正inputAccessoryView的位置,确保和键盘完全对齐:

override func viewDidLoad() {
    super.viewDidLoad()
    automaticallyAdjustsScrollViewInsets = false
    
    // 监听键盘弹出通知
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(keyboardWillShow(_:)),
        name: UIResponder.keyboardWillShowNotification,
        object: nil
    )
}

@objc private func keyboardWillShow(_ notification: Notification) {
    guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
    
    // 计算输入栏的正确位置:屏幕底部 - 键盘高度 - 输入栏高度
    let inputViewY = view.bounds.height - keyboardFrame.height - inputAccessoryView.intrinsicContentSize.height
    inputAccessoryView.frame = CGRect(
        x: 0,
        y: inputViewY,
        width: view.bounds.width,
        height: inputAccessoryView.intrinsicContentSize.height
    )
}

4. 检查全局布局设置

  • 确保Info.plist中的View controller-based status bar appearance设置为YES,保证状态栏布局正确。
  • 如果视图控制器嵌入在导航栏或TabBar中,建议把导航栏/TabBar的isTranslucent设为true,让系统自动处理安全区域适配。

这套方案我之前在项目里用过,完美解决了iPhone X上的键盘显示异常问题,你可以试试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:18:57