We’re working on an app that displays a lot of user-generated data, so we frequently have to deal with the potential for text overflow. Most UI frameworks provide the ability to truncate the text and show an ellipsis (…) to indicate additional text is not shown.
I don’t see a direct way to do this in the new 4.6 UI. Is there any good way to do this manually?
Thanks in advance,
–Bob
Something I’ve been wanting to do for a while now. Create this UI structure in your scene:
- Canvas (default Canvas)
- TextOverflowEllipsis (default Horizontal Layout Group, TextOverflowEllipsis script)
- Text (default Text with some long test text)
- Ellipsis (default Text with text ‘…’, Layout Element with a min width)
And here is the script that goes on the TextOverflowEllipsis gameobject:
using UnityEngine;
using UnityEngine.UI;
public class TextOverflowEllipsis : MonoBehaviour {
public Text text;
public GameObject ellipsis;
RectTransform parentRect;
float textWidth,parentWidth;
string textStr="";
void Start () {
parentRect = GetComponent<RectTransform>();
}
void Update () {
if(text.text != textStr || !parentRect.rect.width.AlmostEquals(parentWidth,.01f)){ //If the current text is not the same as the cached text or the container width changes
CheckTextWidth(); //Check the text's width
textStr = text.text;
}
}
void CheckTextWidth() {
textWidth = LayoutUtility.GetPreferredWidth(text.rectTransform); //This is the width the text would LIKE to be
parentWidth = parentRect.rect.width; //This is the actual width of the text's parent container
ellipsis.SetActive(textWidth > parentWidth); //If the text width is bigger than the container, show the ellipsis
}
}
Just set the Text component of the Text gameobject to the ‘text’ field and the Ellipsis gameobject to the ‘ellipsis’ field in the inspector of the TextOverflowEllipsis gameobject. After that, you can just design the Text and Ellipsis to match your current style.
If anyone is looking for a different solution to this this is how I did it.
I wrote a simple extension to the text class in unity.ui
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class TextTruncExt : Text
{
string updatedText = string.Empty;
protected override void OnPopulateMesh(VertexHelper toFill)
{
Vector2 extents = rectTransform.rect.size;
var settings = GetGenerationSettings(extents);
cachedTextGenerator.Populate(base.text, settings);
float scale = extents.x / preferredWidth;
//text is going to be truncated,
//cant update the text directly as we are in the graphics update loop
if (scale < 1)
{
updatedText = base.text.Substring(0, cachedTextGenerator.characterCount-4);
updatedText += "...";
}
base.OnPopulateMesh(toFill);
}
void Update()
{
if(updatedText != string.Empty && updatedText != base.text)
{
base.text = updatedText;
}
}
}
Its not the most efficient way but it works. It currently just cuts off the string and adds the ellipsis. You could easily make it cut back to the next space then add the ellipsis if you only wanted whole words.
Hope this helps someone.
Hey, this is my (simple) way to do it:
Check the text’s length, as:
if(text.Length > calculatedSize); text.Remove (calculatedSize) + "...";
Simple as that.
I’m trying to figure this out as well. This article is kinda old.
http://forum.unity3d.com/threads/text-clipping-with-dots.201071/
I’m going to post an answer, as this page came up as my first search response, but there’s a very simple solution.
This link has a very simple solution:
public static string Truncate(this string value, int maxChars)
{
return value.Length <= maxChars ? value : value.Substring(0, maxChars) + "...";
}
Usage:
var s = "abcdefg";
Console.WriteLine(s.Truncate(3));
So when setting the text value, you can pass in the text through the truncate function first. You could also create a listener for the text value changing if you wanted to get technical with it. Hope this helps others.
2022 solution:
I set text overflow to ellipsis in the editor window, and then if you need to check in a script if the text is being cut off, you can do:
TMP_Text textComponent = textObject.GetComponent<TMP_Text>();
if(textComponent.isTextTruncated){
//do something
}