SwiftUI中如何在TextField编辑结束后更改文本显示?
聚焦/失焦时动态切换TextField显示内容的实现方案
核心思路是单独维护用户输入的原始值,根据TextField的聚焦状态,动态渲染不同的显示文本:聚焦时展示完整原始值,失焦时替换前3位为xxx,再次聚焦时恢复原始内容。
Flutter 实现示例
import 'package:flutter/material.dart'; class MaskedNumberField extends StatefulWidget { const MaskedNumberField({super.key}); @override State<MaskedNumberField> createState() => _MaskedNumberFieldState(); } class _MaskedNumberFieldState extends State<MaskedNumberField> { final TextEditingController _textController = TextEditingController(); final FocusNode _focusNode = FocusNode(); String _rawInput = ''; // 存储用户输入的真实数字 @override void initState() { super.initState(); // 监听聚焦状态变化,触发UI重绘 _focusNode.addListener(() => setState(() {})); // 监听输入变化,同步更新原始值 _textController.addListener(() { if (_focusNode.hasFocus) { _rawInput = _textController.text; } }); } @override void dispose() { _textController.dispose(); _focusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { String displayContent; if (_focusNode.hasFocus) { displayContent = _rawInput; } else { // 长度≥3时替换前3位,否则保持原内容 displayContent = _rawInput.length >= 3 ? 'xxx${_rawInput.substring(3)}' : _rawInput; } // 同步控制器显示文本,调整光标位置 if (_textController.text != displayContent) { _textController.value = _textController.value.copyWith( text: displayContent, selection: TextSelection.collapsed(offset: displayContent.length), ); } return TextField( controller: _textController, focusNode: _focusNode, keyboardType: TextInputType.number, decoration: const InputDecoration(hintText: "请输入数字"), ); } }
关键细节说明
_rawInput专门存储真实输入内容,避免替换后的文本覆盖原始数据- 通过
FocusNode监听聚焦状态,状态变化时触发UI更新 - 仅在聚焦状态下更新原始值,防止失焦时的替换文本被误存
- 同步控制器文本时调整光标位置,保证输入交互流畅
Web 原生JS 实现示例
<input type="text" id="maskedNumberInput" placeholder="请输入数字"> <script> const inputElement = document.getElementById('maskedNumberInput'); let rawValue = ''; // 聚焦时恢复原始值 inputElement.addEventListener('focus', () => { inputElement.value = rawValue; }); // 失焦时替换前3位 inputElement.addEventListener('blur', () => { if (rawValue.length >= 3) { inputElement.value = 'xxx' + rawValue.substring(3); } else { inputElement.value = rawValue; } }); // 输入时同步原始值(仅聚焦状态下) inputElement.addEventListener('input', () => { if (document.activeElement === inputElement) { rawValue = inputElement.value; } }); </script>
注意事项
- 需处理输入长度不足3位的场景,避免出现无效截取
- 确保原始值的存储独立于显示文本,防止数据丢失
- 输入监听需判断当前聚焦状态,避免失焦时的替换文本污染原始值
内容的提问来源于stack exchange,提问作者Yasuhiro Kondo
相关产品推荐
相关产品推荐

