142 lines
3.4 KiB
C#
142 lines
3.4 KiB
C#
using UnityEngine;
|
|
using TMPro;
|
|
using UnityEngine.EventSystems;
|
|
using System.Collections;
|
|
using UnityEngine.UI;
|
|
|
|
public class CustomTMPInputField : TMP_InputField
|
|
{
|
|
private bool forceFocus = false;
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
//this.contentType=ContentType.IntegerNumber
|
|
//使用字符验证回调
|
|
onValidateInput = OnValidateCharacter;
|
|
// 添加Outline
|
|
Outline ol = gameObject.GetComponent<Outline>();
|
|
if (ol == null) ol = gameObject.AddComponent<Outline>();
|
|
ol.effectColor = new Color32(0xFF, 0xAB, 0x00, 255);
|
|
ol.effectDistance = new Vector2(2, -2);
|
|
ol.enabled = false;
|
|
}
|
|
|
|
// 验证每个输入的字符(核心方法)
|
|
private char OnValidateCharacter(string text, int charIndex, char addedChar)
|
|
{
|
|
// 允许数字 0-9
|
|
if (addedChar >= '0' && addedChar <= '9')
|
|
{
|
|
return addedChar;
|
|
}
|
|
|
|
// 允许小数点 .和-
|
|
if (addedChar == '.'|| addedChar == '-')
|
|
{
|
|
return addedChar; // 允许多个小数点,直接返回
|
|
}
|
|
|
|
// 其他字符不允许输入
|
|
return '\0';
|
|
}
|
|
|
|
public override void OnPointerClick(PointerEventData eventData)
|
|
{
|
|
base.OnPointerClick(eventData);
|
|
if (FocusManager.Instance.currentPage != null)
|
|
{
|
|
FocusManager.Instance.currentPage.UpdateFouceByClick(this);
|
|
|
|
}
|
|
if (!forceFocus)
|
|
{
|
|
Activate();
|
|
}
|
|
}
|
|
|
|
public override void OnDeselect(BaseEventData eventData)
|
|
{
|
|
if (forceFocus)
|
|
{
|
|
StartCoroutine(DelayedSelect());
|
|
}
|
|
else
|
|
{
|
|
base.OnDeselect(eventData);
|
|
}
|
|
}
|
|
|
|
private IEnumerator DelayedSelect()
|
|
{
|
|
yield return null;
|
|
|
|
if (EventSystem.current != null && EventSystem.current.currentSelectedGameObject != gameObject)
|
|
{
|
|
EventSystem.current.SetSelectedGameObject(gameObject);
|
|
|
|
// TMP 原生激活输入框,显示光标
|
|
ActivateInputField();
|
|
// 高亮自己
|
|
Outline ol = gameObject.GetComponent<Outline>();
|
|
if (ol != null) ol.enabled = true;
|
|
// 强制同步 placeholder 状态
|
|
ForceRefresh();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 激活并保持焦点
|
|
/// </summary>
|
|
public void Activate()
|
|
{
|
|
forceFocus = true;
|
|
StartCoroutine(DelayedSelect());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 主动关闭焦点
|
|
/// </summary>
|
|
public void Deactivate()
|
|
{
|
|
forceFocus = false;
|
|
DeactivateInputField();
|
|
|
|
if (EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject)
|
|
EventSystem.current.SetSelectedGameObject(null);
|
|
|
|
ForceRefresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否有焦点
|
|
/// </summary>
|
|
public bool HasFocus()
|
|
{
|
|
return forceFocus && isFocused;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 手动切换到另一个输入框
|
|
/// </summary>
|
|
public void SwitchFocus(CustomTMPInputField nextField)
|
|
{
|
|
if (nextField == null) return;
|
|
|
|
ForceRefresh();
|
|
Deactivate();
|
|
|
|
nextField.Activate();
|
|
nextField.ForceRefresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 强制刷新 placeholder 状态
|
|
/// </summary>
|
|
public void ForceRefresh()
|
|
{
|
|
if (placeholder != null)
|
|
placeholder.gameObject.SetActive(string.IsNullOrEmpty(text) && !isFocused);
|
|
}
|
|
}
|