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

从Nib加载自定义inputAccessoryView出现宽度为0的错误排查

解决InputAccessoryView点击内部TextView弹出键盘时宽度为0的警告问题

这个问题我之前也碰到过,本质是你的CustomInputAccessoryView的intrinsicContentSize设置和布局约束绑定方式不对,导致系统在键盘弹出重新计算布局时无法正确识别视图的宽度。下面是具体的解决方案:

问题原因分析

  1. 你重写的intrinsicContentSize返回了CGSize.zero,这会让系统认为这个视图没有固有尺寸,当键盘弹出触发布局更新时,系统无法正确计算宽度,就会抛出那个警告。
  2. 你在setupInputAccessoryView里直接设置containerView.frame = self.bounds,这种方式在布局动态变化(比如键盘弹出)时会失效,因为AutoLayout会覆盖手动设置的frame。

具体修复步骤

1. 修正intrinsicContentSize

inputAccessoryView的宽度会由系统自动匹配当前窗口的宽度,我们只需要指定正确的高度即可。修改intrinsicContentSize的实现:

override var intrinsicContentSize: CGSize {
    // 这里的height换成你实际需要的高度,比如60
    return CGSize(width: UIView.noIntrinsicMetric, height: 60)
}

UIView.noIntrinsicMetric告诉系统我们不需要指定固有宽度,由系统自动适配窗口。

2. 用AutoLayout约束替代手动设置frame

在setupInputAccessoryView里,去掉containerView.frame = self.bounds,换成添加AutoLayout约束,让containerView完全填充父视图:

func setupInputAccessoryView() {
    self.translatesAutoresizingMaskIntoConstraints = false
    Bundle.main.loadNibNamed("CustomInputAccessoryView", owner: self, options: nil)
    addSubview(containerView)
    // 禁用containerView的自动转换约束,然后添加四边约束
    containerView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        containerView.topAnchor.constraint(equalTo: self.topAnchor),
        containerView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
        containerView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
        containerView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
    ])
}

这样不管父视图的frame怎么变化,containerView都会自动填充。

3. 确保XIB内的约束正确

检查你的XIB文件:

  • 确保containerView内部的控件(button1、button2、textView)都有正确的约束,比如textView的宽度和containerView关联,按钮有固定宽度和位置约束,避免出现布局冲突。
  • 确认XIB的File's Owner已经正确设置为CustomInputAccessoryView,所有IBOutlet都关联正确。

修改后的完整代码

class CustomInputAccessoryView: UIView { 
    @IBOutlet var containerView: UIView! 
    @IBOutlet var contentView: UIView! 
    @IBOutlet weak var button1: UIButton! 
    @IBOutlet weak var button2: UIButton! 
    @IBOutlet weak var textView: UITextView! 

    override var intrinsicContentSize: CGSize { 
        return CGSize(width: UIView.noIntrinsicMetric, height: 60) // 替换为你的实际高度
    } 

    override init(frame: CGRect) { 
        super.init(frame: frame) 
        setupInputAccessoryView() 
    } 

    required init?(coder aDecoder: NSCoder) { 
        super.init(coder: aDecoder) 
        setupInputAccessoryView() 
    } 

    func setupInputAccessoryView() { 
        self.translatesAutoresizingMaskIntoConstraints = false 
        Bundle.main.loadNibNamed("CustomInputAccessoryView", owner: self, options: nil) 
        addSubview(containerView) 
        // 使用AutoLayout约束containerView
        containerView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor),
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor)
        ])
    } 
}

这样修改后,你的inputAccessoryView会始终和窗口宽度一致,点击textView弹出键盘时也不会再出现那个宽度为0的警告了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:48:47