killapp/Assets/Scripts/UI/Components/VerificationCodeInput.cs
2026-04-16 14:57:19 +08:00

278 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using UnityEngine;
using UnityEngine.UI;
namespace Kill.UI.Components
{
/// <summary>
/// 验证码输入组件
/// 使用方式:
/// 1. 在场景中创建一个空物体,挂载此脚本
/// 2. 创建n个Text作为验证码显示位
/// 3. 创建一个InputField作为隐藏输入框可设置为透明或移出屏幕外
/// 4. 在Inspector中配置digitTexts和inputField
/// </summary>
public class VerificationCodeInput : MonoBehaviour
{
[Header("验证码配置")]
[Tooltip("验证码位数")]
[Range(1, 10)]
public int codeLength = 6;
[Tooltip("是否自动验证 - 输入完成后自动触发OnCodeCompleted事件")]
public bool autoSubmit = true;
[Tooltip("是否只允许数字")]
public bool numericOnly = true;
[Header("UI引用")]
[Tooltip("验证码显示文本数组,按顺序从左到右")]
public Text[] digitTexts;
[Tooltip("隐藏的输入框(用于接收用户输入)")]
public InputField inputField;
[Header("样式配置")]
[Tooltip("未输入时的占位字符")]
public string placeholderChar = "-";
[Tooltip("输入完成后的字符(如需要隐藏可设为*")]
public string displayChar = "";
public event Action<string> OnCodeCompleted;
public event Action<string> OnCodeChanged;
private string currentCode = "";
private void Awake()
{
Initialize();
}
private void OnEnable()
{
if (inputField != null)
{
inputField.onValueChanged.AddListener(HandleInputChanged);
inputField.onEndEdit.AddListener(HandleEndEdit);
}
}
private void OnDisable()
{
if (inputField != null)
{
inputField.onValueChanged.RemoveListener(HandleInputChanged);
inputField.onEndEdit.RemoveListener(HandleEndEdit);
}
}
private void Start()
{
RefreshDisplay();
}
/// <summary>
/// 初始化组件
/// </summary>
private void Initialize()
{
if (inputField == null)
{
inputField = GetComponentInChildren<InputField>();
}
if (digitTexts == null || digitTexts.Length == 0)
{
digitTexts = GetComponentsInChildren<Text>();
}
if (digitTexts != null && digitTexts.Length > 0)
{
codeLength = Mathf.Min(codeLength, digitTexts.Length);
}
if (inputField != null)
{
inputField.characterLimit = codeLength;
inputField.contentType = numericOnly
? InputField.ContentType.IntegerNumber
: InputField.ContentType.Alphanumeric;
var inputText = inputField.textComponent;
if (inputText != null)
{
inputText.color = new Color(1, 1, 1, 0);
}
if (inputField.placeholder != null)
{
var placeholder = inputField.placeholder.GetComponent<Text>();
if (placeholder != null)
{
placeholder.color = new Color(1, 1, 1, 0);
}
}
}
}
/// <summary>
/// 处理输入变化
/// </summary>
private void HandleInputChanged(string value)
{
if (numericOnly)
{
value = FilterNumeric(value);
if (inputField != null && inputField.text != value)
{
inputField.text = value;
return;
}
}
if (value.Length > codeLength)
{
value = value.Substring(0, codeLength);
if (inputField != null)
{
inputField.text = value;
return;
}
}
currentCode = value;
RefreshDisplay();
OnCodeChanged?.Invoke(currentCode);
if (autoSubmit && currentCode.Length == codeLength)
{
Debug.Log("自动提交");
OnCodeCompleted?.Invoke(currentCode);
}
}
/// <summary>
/// 处理结束编辑(用户按下回车或失去焦点)
/// </summary>
private void HandleEndEdit(string value)
{
if (!autoSubmit && currentCode.Length == codeLength)
{
OnCodeCompleted?.Invoke(currentCode);
}
}
/// <summary>
/// 刷新显示
/// </summary>
private void RefreshDisplay()
{
if (digitTexts == null) return;
for (int i = 0; i < digitTexts.Length; i++)
{
if (digitTexts[i] == null) continue;
if (i < currentCode.Length)
{
char c = currentCode[i];
digitTexts[i].text = string.IsNullOrEmpty(displayChar) ? c.ToString() : displayChar;
}
else
{
digitTexts[i].text = placeholderChar;
}
}
}
/// <summary>
/// 过滤非数字字符
/// </summary>
private string FilterNumeric(string input)
{
var result = "";
foreach (char c in input)
{
if (char.IsDigit(c))
{
result += c;
}
}
return result;
}
/// <summary>
/// 获取当前验证码
/// </summary>
public string GetCode()
{
return currentCode;
}
/// <summary>
/// 设置验证码(用于自动填充等)
/// </summary>
public void SetCode(string code)
{
if (code == null)
{
code = "";
}
if (code.Length > codeLength)
{
code = code.Substring(0, codeLength);
}
currentCode = code;
if (inputField != null)
{
inputField.text = currentCode;
}
RefreshDisplay();
OnCodeChanged?.Invoke(currentCode);
if (currentCode.Length == codeLength)
{
OnCodeCompleted?.Invoke(currentCode);
}
}
/// <summary>
/// 清空输入
/// </summary>
public void Clear()
{
currentCode = "";
if (inputField != null)
{
inputField.text = "";
}
RefreshDisplay();
}
/// <summary>
/// 让输入框获得焦点
/// </summary>
public void Focus()
{
if (inputField != null)
{
inputField.ActivateInputField();
}
}
/// <summary>
/// 检查验证码是否输入完整
/// </summary>
public bool IsComplete()
{
return currentCode.Length == codeLength;
}
}
}