Unity中TMP_InputField DD-MM-YYYY日期正则掩码光标后移问题及解决
问题原因
- 对
inputField.text赋值时,TMP_InputField会默认将光标重置到文本起始位置,原有逻辑仅执行caretPosition++的硬编码增量,没有匹配正则替换后实际的文本长度变化。比如输入3位数字123时,正则会插入1个-变为12-3,文本长度从3变为4,赋值后光标默认回到0位,仅+1会让光标停在第1位,视觉上就是后退了1位。 - 硬编码的光标增量逻辑无法适配删除、选中修改等非连续输入的场景,容易出现位置偏移。
- 未判断文本是否实际发生变化就直接赋值,会重复触发
onValueChanged事件,也会导致不必要的光标重置。
修复方案
- 文本修改完成后,直接将
caretPosition设置为当前文本的总长度,保证光标永远定位在末尾,替换硬编码的增量逻辑。 - 新增文本变化判断和更新锁,仅当正则处理后的内容和原始输入不一致时才给
inputField.text赋值,避免递归触发事件和不必要的光标重置。 - 新增最大长度限制,避免输入超过10位(DD-MM-YYYY格式总长度为10)的无效内容。
修复后代码
using System.Collections; using UnityEngine; using UnityEngine.UI; using System.Text.RegularExpressions; using TMPro; public class InputDateMask : MonoBehaviour { public TMP_InputField inputField; // 加锁避免递归触发onValueChanged private bool isUpdating = false; private void Awake () { inputField.onValueChanged.AddListener (delegate { OnValueChanged (); }); // 直接设置最大输入长度,减少无效输入处理 inputField.characterLimit = 10; } public void OnValueChanged () { if (isUpdating || string.IsNullOrEmpty(inputField.text)) { return; } isUpdating = true; string originalInput = inputField.text; string MatchPattern = @"^((\d{2}-){0,2}(\d{1,2})?)$"; string ReplacementPattern = "$1-$3"; string ToReplacePattern = @"((\.?\d{2})+)(\d)"; string processedInput = Regex.Replace(originalInput, ToReplacePattern, ReplacementPattern); Match result = Regex.Match(processedInput, MatchPattern); if (result.Success && processedInput != originalInput) { inputField.text = processedInput; // 直接设置光标到文本末尾,无需硬编码增量 inputField.caretPosition = processedInput.Length; } isUpdating = false; } }
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

