UE4中EditableText 组件,在PC端或者IOS端等输入中文的时候,会将中文拼音也同步输入到编辑框中
组件会在每一次有输入的时候触发OnTextChanged事件
这个事件传递过来的参数是所输入的所有的字符,包括拼音。
我们监听这个函数一般有两个需求:
(1)实时统计输入的字符个数
(2)检测输入的字符是否达到最大值,如果达到最大值则进行截取
这个时候,就会有一个问题,比如上面的截图,我们真实输入的字符是 “你好” 这个两个字符,但我们通过这个事件的参数获取的字符串是 "你好shi'jie" 这9个字符。这个时候字符长度统计就和我们需求的不一致了,我们希望能够将当前输入的拼音从这个字符串中去除,统计其他字符串长度。
但是去除拼音这个操作,我们不太好控制,因为有时候我们输入的最终结果就是拼音,你不能不让人家输入吧。
我们希望的时候,在我们进行字符个数统计的时候,当前不是在输入拼音状态。
所以在接收到OnTextChanged事件的时候,只要可以判断当前不是输入拼音的状态,就可以放心大胆的去统计字符个数了,如果是输入拼音状态,则我们不进行任何操作即可。
那如何判断当前是输入拼音状态呢,我们通过查看源码发现,每次输入拼音的时候都会进入组装状态,也就是预备输入状态,该状态下输入的文本在退出改模式的时候会被最终输入的文本替换。
想要了解的可以看看源码断点试试: FTextStoreACP.cpp
(1)进入组装模式 OnStartComposition
(2)接受输入的文本 SetText
(3)更新组装长度 OnUpdateComposition
(4)退出组装模式 OnEndComposition
EditableText文本的布局文件是 FSlateEditableTextLayout.cpp
(1)进入组装模式 BeginComposition
(2)接受输入的文本 SetTextInRange
(3)更新组装长度 UpdateCompositionRange
(4)退出组装模式 EndComposition
看过源码,我们发现,在该模式下输入的文本,都会调用SetTextInRange这个函数。
在这个文件中,重写的SetTextInRange函数主要是更新布局,保存文本,并且触发文本变动事件。
但我们其实不想在组装状态的时候,接收这个文本变动事件,只需要在退出组装状态的时候触发这
个文本变动事件即可。
我们看到源码中,退出组装状态的时候,确实也会触发一次文本变动事件,那我们直接把SetTextInRange里面的文本变动事件屏蔽掉就可以了。
测试了一下,完全没问题。