滚动InputField
背景
因为inputField的文本框Text是固定大小,无法伸缩的,超框内容以及光标在文字间移动,是通过实时刷新Text的内容来实现的 ,所以希望实现inputField 的滚动就需要我们特殊处理
实现方式
希望实现滚动效果,最方便的还是借助Scroll
由此,我查阅总结了下,大概有两种较为方便的实现方式
滚动,伪动态扩展
- 直接创立一个新的scroll, 然后在content下创建我们需要的 inputField的 组件,
- 将InputField的对齐方式设为顶对齐,两边扩展(适用于纵向滚动,横向滚动同理调整),高度拉到一个很高的高度(确定能容纳最大的字数不会超框,故仅适用于字数不多,且限制确定的情况)
- 在content上挂一个text的组件,颜色设为透明,并挂载contentSizeFillter组件
- 在inputField组件的onValueChange的监听函数内,实时将输入的内容赋给content上的text
- 就可以达到content的自动扩展并滚动,效果看起来就是inputField在滚动了
滚动,真动态扩展
- 创建一个scroll组件,直接将content组件删除,替换为我们需要的 inputField组件,挂在Scroll组件的content里
- 对齐方式设为顶部居中对齐,pivot的y设为1(用于纵向扩展时,框体向下延伸)
- 在inputFiled的onVlauehChange的监听中,实时更新inputFiled的高度sizeData.y
local orginHeight -- 记录scroll的高度
local inputCom -- inputField的控件
local inputTrans -- inputField的RectTransform
if inputCom.preferredHeight > originHeight or inputTrans.sizeDelta.y >= originHeight then
-- 加10 是为了增加容错,避免inputfield的文字边缘被scroll裁剪掉
local newHeight = math.max(originHeight, inputCom.preferredHeight + 10)
inputTrans.sizeDelta = Vector2.New(inputTrans.sizeDelta.x, newHeight)
end
自动聚焦功能
背景
需要能在滚动的inputField中, 自动聚焦(滚动)到某一行出现在屏幕上(不被scroll的mask遮挡裁剪)
实现方式
- inputField本身是可以通过改变光标位置 caretPosition索引聚焦到文本框外的文本内容,但增加了scroll让inputField动态扩展后,inputField的所有文本就都在文本框内了;
- scroll内聚焦动态扩展的inputField的某一行,其实就是移动input的位置,让该行显示在scroll的范围内
- 思路就是计算inputField内该行文字的相对高度,再修改inputField的Y轴位置就可以了
local gen = inputCom.textComponent.cachedTextGenerator
local line
-- 计算需要显示的文字在哪一行
-- index是需要聚焦的文字在inputField中的索引位置
for i = 1, gen.lineCount - 1 do
if index < gen.lines[i].startCharIdx then
line = i - 1
break
end
end
if not line then
line = gen.lineCount - 1
end
--计算偏移量,就是input的Y轴位置
-- scaleH 是屏幕适配的缩放比例,没有就不需要处理
-- scrollInputTrans是scroll的RectTransform
local height = (gen.lines[0].topY - gen.lines[line].topY) / scaleH
local finalPosY = height - scrollInputTrans.rect.height/2
finalPosY = math.min(math.max(0, finalPosY), inputTrans.rect.height - scrollInputTrans.rect.height)
inputTrans.anchoredPosition = Vector2.New(inputTrans.anchoredPosition.x, finalPosY)