当前位置: 首页 > news >正文

「Unity3D」TextMeshPro使用TMP_InputField实现,输入框高度自动扩展与收缩

先看实现效果:

要实现这个效果,有三个方面的问题需要解决:

第一,输入框的高度扩展,内部子元素会随着锚点,拉伸变形——要解决这个问题,需要将内部元素改变父类,然后增加父类高度,再恢复父类,这样内部元素(如图中两个按钮),就不会随着高度增加,而拉伸变形。类似代码如下:

private void ChangeInputHeight(float heightChange)
{// disable the effect of parent size changes on child layoutsthis.finishRecordRT.SetParent(null);this.recordRT      .SetParent(null);if (heightChange != 0.0f){this.inputFieldRT.SetRelativeSizeY(heightChange);this.inputBarHeightChange += heightChange;}else {this.inputFieldRT.SetRelativeSizeY(-this.inputBarHeightChange);this.inputBarHeightChange = 0.0f;}this.finishRecordRT.SetParent(this.inputBarRT);this.recordRT      .SetParent(this.inputBarRT);
}

第二,注册inputField.onValueChanged去监听,输入框的文本变化,并通过inputField.textComponent.textInfo的行变化,去判断换行发生。

private void OnInputFieldValueChanged(string text)
{var textInfo  = this.inputField.textComponent.textInfo;var lineCount = textInfo.lineCount;if (this.inputFieldPreTextLineCount != lineCount){this.ChangeInputHeight(this.inputFieldLineHeight * (lineCount - this.inputFieldPreTextLineCount));this.inputFieldPreTextLineCount = lineCount;}
}

这里需要记录之前的行数,即inputFieldPreTextLineCount,然后对比变化后的行数,就可以知道是否换行,以及换了几行。

第三,InputField换行后(输入换行符),无法直接触发行数变化,需要输入一个字符后才行,所以需要自行判断,键入了换行符。但删除换行符后,就会触发行数变化,这个删除逻辑就是需要的。

    if (this.inputFieldPreTextLineCount != lineCount){this.ChangeInputHeight(this.inputFieldLineHeight * (lineCount - this.inputFieldPreTextLineCount));this.inputFieldPreTextLineCount = lineCount;}else{// inputField.text equal to text, not equal to inputField.textComponent.text (textInfo)// when adds    chars, the textInfo.characterCount equal to the text.Length// when removes chars, the textInfo.characterCount is more than text.Length (because adds extra space \u200B)if (textInfo.characterCount == text.Length && text[^1] == '\n'){this.ChangeInputHeight(this.inputFieldLineHeight);++this.inputFieldPreTextLineCount;}}

这里增加的逻辑就是:当行数没变的时候,需要检测text的最后一个字符,是否是换行符——如果是,就增加高度,而删除则可以通过行数变化处理,包括一次删除多行。

为什么要加一个textInfo.characterCount == text.Length的判断?

因为,只有在输入字符的时候,才会成立——而删除字符的时候不成立,这样就会剔除,删除换行符是最后一个,但还没删除它,此时行数也没变化。

而之所以,删除字符的时候不成立——是因为,在删除字符的时候,InputField的代码显示,会增加看不见的标识字符,即\u200B——因此,inputField.textComponent.text(textInfo)text(inputField.text)的内容会不一致。  

相关文章:

  • Java IO流与NIO终极指南:从基础到高级应用
  • JAVA入门-JAVA数据类型
  • 永磁同步电机控制算法--线性ADRC转速环控制器(一阶、二阶)
  • Keysight万用表使用指南及基于Python采集数据生成Excel文件
  • Python os.path.join()路径拼接异常
  • 如何解决matlab/octave画图legend图例颜色一样的问题?
  • 零基础做自动驾驶集成测试(仿真)
  • C# 高效操作excel文件
  • Elasticsearch--自带“搜索引擎“的数据库
  • 软考中级-软件设计师 操作系统(手写笔记)
  • 基础术语说明
  • 负载均衡技术全景指南:架构、算法与发展趋势
  • Qwen3 模型架构和能力概览
  • Compose笔记(二十)--TextField
  • MCP协议:自然语言与结构化数据的双向桥梁 ——基于JSON-RPC 2.0的标准化实践
  • 遗传算法(Genetic Algorithm,GA)
  • 健康管理系统操作界面解析:从建档到干预方案生成的极简逻辑
  • Vulkan 学习(16)---- 使用 VertexBuffer
  • Windows系统安装Docker(Win10系统升级,然后安装)
  • 区块链:跨链协的技术突破与产业重构
  • 过去24小时中美是否就关税问题进行过接触?外交部:没有
  • 五部门:开展新就业形态劳动者劳动权益保障水平提升专项行动
  • 阿斯利康中国区一季度收入增5%,或面临最高800万美元新罚单
  • 解放日报:中国大模型企业的发展机遇已经到来
  • 华夏银行一季度营收降逾17%、净利降逾14%,公允价值变动损失逾24亿
  • 首映|“凤凰传奇”曾毅:拍电影,我是认真的