You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 12:35:05