先看實現效果:
要實現這個效果,有三個方面的問題需要解決:
第一,輸入框的高度擴展,內部子元素會隨著錨點,拉伸變形——要解決這個問題,需要將內部元素改變父類,然后增加父類高度,再恢復父類,這樣內部元素(如圖中兩個按鈕),就不會隨著高度增加,而拉伸變形。類似代碼如下:
private void ChangeInputHeight(float heightChange)
{// disable the effect of parent size changes on child layoutsthis.finishRecordRT.SetParent(null);this.recordRT .SetParent(null);if (heightChange != 0.0f){this.inputFieldRT.SetRelativeSizeY(heightChange);this.inputBarHeightChange += heightChange;}else {this.inputFieldRT.SetRelativeSizeY(-this.inputBarHeightChange);this.inputBarHeightChange = 0.0f;}this.finishRecordRT.SetParent(this.inputBarRT);this.recordRT .SetParent(this.inputBarRT);
}
第二,注冊inputField.onValueChanged去監聽,輸入框的文本變化,并通過inputField.textComponent.textInfo的行變化,去判斷換行發生。
private void OnInputFieldValueChanged(string text)
{var textInfo = this.inputField.textComponent.textInfo;var lineCount = textInfo.lineCount;if (this.inputFieldPreTextLineCount != lineCount){this.ChangeInputHeight(this.inputFieldLineHeight * (lineCount - this.inputFieldPreTextLineCount));this.inputFieldPreTextLineCount = lineCount;}
}
這里需要記錄之前的行數,即inputFieldPreTextLineCount,然后對比變化后的行數,就可以知道是否換行,以及換了幾行。
第三,InputField換行后(輸入換行符),無法直接觸發行數變化,需要輸入一個字符后才行,所以需要自行判斷,鍵入了換行符。但刪除換行符后,就會觸發行數變化,這個刪除邏輯就是需要的。
if (this.inputFieldPreTextLineCount != lineCount){this.ChangeInputHeight(this.inputFieldLineHeight * (lineCount - this.inputFieldPreTextLineCount));this.inputFieldPreTextLineCount = lineCount;}else{// inputField.text equal to text, not equal to inputField.textComponent.text (textInfo)// when adds chars, the textInfo.characterCount equal to the text.Length// when removes chars, the textInfo.characterCount is more than text.Length (because adds extra space \u200B)if (textInfo.characterCount == text.Length && text[^1] == '\n'){this.ChangeInputHeight(this.inputFieldLineHeight);++this.inputFieldPreTextLineCount;}}
這里增加的邏輯就是:當行數沒變的時候,需要檢測text的最后一個字符,是否是換行符——如果是,就增加高度,而刪除則可以通過行數變化處理,包括一次刪除多行。
為什么要加一個textInfo.characterCount == text.Length的判斷?
因為,只有在輸入字符的時候,才會成立——而刪除字符的時候不成立,這樣就會剔除,刪除換行符是最后一個,但還沒刪除它,此時行數也沒變化。
而之所以,刪除字符的時候不成立——是因為,在刪除字符的時候,InputField的代碼顯示,會增加看不見的標識字符,即\u200B——因此,inputField.textComponent.text(textInfo)與text(inputField.text)的內容會不一致。??