記錄一個在使用FairyGUI的TextField時遇到的坑。
TextField有一個文本模板功能,可以實現類似占位符的功能,如:{ number = 0 }
,然后我們可以在腳本中修改number的值:textField.SetVar("number", "1").FlushVars();
。運行時我們會發現,我們可以成功獲取UI下的TextField,但修改操作卻無法生效,實在讓人費解。
接下來就是漫長的源碼測試環節。
public GTextField SetVar(string name, string value)
{
if (_templateVars == null)
_templateVars = new Dictionary<string, string>();
_templateVars[name] = value;
return this;
}
首先是SetVar()
,這個只是修改模板信息,通過Log
輸出后排除。那么問題只能是在FlushVars()
,也就是刷新文本上。
public void FlushVars()
{
SetTextFieldText();
UpdateSize();
}
virtual protected void SetTextFieldText()
{
string str = _text;
if (_templateVars != null)
str = ParseTemplate(str);
_textField.maxWidth = maxWidth;
if (_ubbEnabled)
_textField.htmlText = UBBParser.inst.Parse(XMLUtils.EncodeString(str));
else
_textField.text = str;
}
觀察上面的代碼可以發現,文本的轉換發生在ParseTemplate()
,問題極有可能是出在這上面,翻看源碼,ParseTemplate()
其實是一個暴力的字符串處理方法,首先找出所有配對的{}
,然后獲取_templateVars
中的key/value
對,去逐個匹配文本中的模板,下面是關鍵的key/value
獲取部分代碼。
tag = template.Substring(pos1 + 1, pos2 - pos1 - 1);
pos3 = tag.IndexOf('=');
if (pos3 != -1)
{
if (!_templateVars.TryGetValue(tag.Substring(0, pos3), out value))
value = tag.Substring(pos3 + 1);
}
else
{
if (!_templateVars.TryGetValue(tag, out value))
value = "";
}
可以看出,這個key和value匹配是很嚴格的,不允許出現任何冗余字符,包括空格,或者說,這是一個純字符串的匹配(可以說是很臭了,空格產生美都不允許)。在我們把模板內的所有空格去掉后,腳本就可以控制number的值了。