
image.png
下列均以Lua代碼編寫實(shí)現(xiàn)
主要思路:
- 根據(jù)高度判斷是否需要裁剪多余行內(nèi)容
- 存儲(chǔ)富文本
- 移除富文本
- 切割多余文本
- 恢復(fù)富文本
根據(jù)高度判斷是否需要裁剪多余行內(nèi)容
txt:Unity - Text組件(UnityEngine.UI.Text)
height:計(jì)算當(dāng)前內(nèi)容占用總高度
one_height:一行內(nèi)容的高度
local generator = CS.UnityEngine.TextGenerator()
local settings = txt:GetGenerationSettings(size)
local height = generator:GetPreferredHeight(content, settings)
local one_height = generator:GetPreferredHeight(" ", settings)
存儲(chǔ)富文本
local matchs = {} -- 存儲(chǔ)富文本匹配內(nèi)容
local last_start = 0
for str in string.gmatch(content, "<[^>]->") do
local start_idx, end_idx = string.find(content, str, last_start)
last_start = start_idx
table.insert(matchs, {str = str, start_idx = start_idx, end_idx = end_idx})
end
移除富文本
-- 根據(jù)存儲(chǔ)的matchs匹配移除
for i, v in ipairs(matchs) do
content = string.gsub(content, v.match_str or v.str, "")
end
切割多余文本
-- 判斷字符對(duì)應(yīng)byte長度
function UTF8LenWord(char)
if not char then
return 0
elseif char > 240 then
return 4
elseif char > 225 then
return 3
elseif char > 192 then
return 2
end
return 1
end
local len = string.len(content)
local char_lens = {} -- 記錄每個(gè)文字的byte長度,后面一個(gè)一個(gè)切割掉
local idx = 1
while(idx <= len) do
local c = UTF8LenWord(string.byte(content, idx, idx + 1))
table.insert(char_lens, 1, c)
idx = idx + c
end
-- 行數(shù)大于1行的根據(jù)長度記錄進(jìn)行剔除
while(height/one_height > 1) do
local sub_count = table.remove(char_lens, 1)
len = len - sub_count
content = string.sub(content, 0, len)
height = generator:GetPreferredHeight(content, settings)
end
-- 最后剔除掉3+個(gè)byte
local sub_count = 0
while(sub_count < 3) do
sub_count = sub_count + table.remove(char_lens, 1)
end
content = string.sub(content, 0, len - sub_count) .. "..."
恢復(fù)富文本
-- 最后根據(jù)富文本記錄恢復(fù)富文本
for i, v in ipairs(matchs) do
local len = string.len(content)
local start_idx = v.start_idx - 1
if start_idx > len then
-- 一般富文本帶'/'的作為結(jié)尾,匹配不到'/'的且已經(jīng)超過文本長度時(shí),就不繼續(xù)執(zhí)行了
if not string.match(v.str, "/") then
break
end
start_idx = len
end
local left = string.sub(content, 1, start_idx)
local right = string.sub(content, start_idx + 1, len)
content = left .. v.str .. right
end
print(content)