Content size fitter callback

I use UI to display a scroll panel in which I put several Texts dynamically.
These Text elements have a content size fitter.
If I try to get the size of these Texts right after I create it, I get the default size, not the size after the content size fitter was applied.
I search about a callback called when the text was resized by the fitter but I found anything.

How can I detect when the content size fitter was applied ?

Same problem here, found a solution @klem ?

Edit: Found a solution, but a not-so-neat one. I’ve put it in a coroutine and this does work.
Same situation as klem described, assigned a new text, but the size keeps the old one.
Does it has something to do with the frames of something?

Anyway, put it in an coroutine and it gives the new size immediately

gameObject.GetComponentInChildren().text = nums [i, 0];
Debug.Log(gameObject.GetComponentInChildren().rectTransform.sizeDelta);

Edit 2: Not entirely true, still had to put an yield return 0 in it before it updated, so I guess the sizes get updated at the end of each frame.

Taken from a separate post: finding the size of a content size fitter - Unity Engine - Unity Discussions

I achieved that by using UIBehaviour which contains Event when a Rectransform is resizing

I created a Popup script derived from UIBehaviour, and then overrided the method OnRectTransformDimensionsChange

1 Like

Canvas.ForceUpdateCanvases(); before get size

1 Like

Hi, I meet the similar situation. I want to get the current text game object’s width of its rect transform.
But the width value seems to be always delayed, maybe it will be calculated in next frame by ContentSizeFitter component. After I check the Unity document, I found the system will call SetLayoutHorizontal method to adjust the size of a game object automatically. So, I force it to adjust the size of game object immediately by calling that method. Then problem solved.

ContentSizeFitter fitter = theGameObjectHasSizeFitter.GetComponent ();
fitter.SetLayoutHorizontal ();

2 Likes

thanks, this works!

Wow guys, how come no one votes this up?! This is brilliant and is the most flexible solution!

I wrote a quick helper based on this idea:

using UnityEngine;
using UnityEngine.EventSystems;

public class ContentSizeFitterHelper : UIBehaviour
{
    public bool maintainParentSize;
    public Vector2 parentSizeOffset;
    public Vector2 minSizeToStartMaintain;
    public RectTransform targetParent;
    private RectTransform rectT;

    protected override void OnRectTransformDimensionsChange()
    {
        base.OnRectTransformDimensionsChange();
        if (maintainParentSize)
        {
            if (rectT == null)
            {
                rectT = gameObject.GetComponent<RectTransform>();
            }
           
            if (rectT.rect.width >= minSizeToStartMaintain.x || rectT.rect.height >= minSizeToStartMaintain.y)
            {
                if (targetParent == null)
                {
                    targetParent = GetComponentInParent<RectTransform>();
                }

                targetParent.sizeDelta = new Vector2(rectT.rect.width + parentSizeOffset.x, rectT.rect.height + parentSizeOffset.y);
            }
        }
    }
}

use this
text.rectTransform.sizeDelta = new Vector2 (text.preferredWidth,text.preferredHeight);
backGround.sizeDelta = new Vector2 (text.preferredWidth+20.0f,text.preferredHeight+20.0f);