UGUI内核大探究(十六)InputField

InputField是UGUI的重要组件,可以提供文本输入功能,是与用户交互的一个重要手段。我们可以在编辑器里,为OnValueChanged和OnEndEdit两个事件添加监听,这样就可以获得用户输入的文本。本文就探究一下InputField的实现原理。

按照惯例,附上UGUI源码下载地址

在编辑器新建一个InputField,它会附带两个子对象Placeholder和Text。


Placeholder(占位符)是当输入文字为空时显示的提示文字,Text显示的便是输入文字。

我们先看一下InputField的继承关系:

    public class InputField
        : Selectable,
        IUpdateSelectedHandler,
        IBeginDragHandler,
        IDragHandler,
        IEndDragHandler,
        IPointerClickHandler,
        ISubmitHandler,
        ICanvasElement

InputField重写了OnEnable(调用时机参见Untiy3D组件小贴士(一)OnEnabled与OnDisabled)方法,方法里设置了一些变量,然后调用了m_TextComponent的RegisterDirtyVerticesCallback方法两次,添加MarkGeometryAsDirty和UpdateLabel回调,最后再调用一下UpdateLabelm_TextComponent对应的是Text对象的Text组件,而RegisterDirtyVerticesCallback则是Graphic的方法(Text间接继承自Graphic),当Graphic需要重建Mesh(将顶点数据设为脏的)的时候,会回调方法。MarkGeometryAsDirty方法将自己注册到CanvasUpdateRegistry的图像重建序列(参考UGUI内核大探究(六)CanvasUpdateRegistry)。

        /// <summary>
        /// Update the visual text Text.
        /// </summary>

        protected void UpdateLabel()
        {
            if (m_TextComponent != null && m_TextComponent.font != null && !m_PreventFontCallback)
            {
                // TextGenerator.Populate invokes a callback that's called for anything
                // that needs to be updated when the data for that font has changed.
                // This makes all Text components that use that font update their vertices.
                // In turn, this makes the InputField that's associated with that Text component
                // update its label by calling this UpdateLabel method.
                // This is a recursive call we want to prevent, since it makes the InputField
                // update based on font data that didn't yet finish executing, or alternatively
                // hang on infinite recursion, depending on whether the cached value is cached
                // before or after the calculation.
                //
                // This callback also occurs when assigning text to our Text component, i.e.,
                // m_TextComponent.text = processed;

                m_PreventFontCallback = true;

                string fullText;
                if (Input.compositionString.Length > 0)
                    fullText = text.Substring(0, m_CaretPosition) + Input.compositionString + text.Substring(m_CaretPosition);
                else
                    fullText = text;

                string processed;
                if (inputType == InputType.Password)
                    processed = new string(asteriskChar, fullText.Length);
                else
                    processed = fullText;

                bool isEmpty = string.IsNullOrEmpty
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值