How to set UI Rect Scroll for dynamically growing content?

Could anyone kindly guide, how to use UI Rect Scroll for a content that might grown dynamically by adding content after a web service call or with respect to some button response by the user in game interface.

Following the tutorial available on Unity website, it show how to scroll an image which is greater in size than the scroll rect, but how to get this setup working for stuffs that might be added to the panel later in game or runtime, which will increase in height or width but still the scroll will reflect to the old height or width, rather than the new dimensions.

Kindly have a look at following image.

[36550-ui+scroll+rect.png|36550]

Could anyone guide me on this front.

Humble Regards,
Sharat Achary

12 Answers

12

This link solved my problem, I’m sure it helps you too.

Thanks this is the best solution because it does not require code to calculate the size.

THANK YOU!!! i had no idea this simple component “Content Size Fitter” existed, that solved my problem

Helped, thanks!

This is a much better answer & a solid one. A breeze.

Still working in 2019.3, thanks!

Find the attached demo.
You can add objects under “Grid-Dynamic” gameobject dynamically and scrolling works fine.

Thanks for this. :D :D

I sent you some rep. This comment seriously made my day. I've been fighting with the ScrollRect forever and never had a good solution.

Excellent demo. Thanks for sharing the code.

Hi, I need this too but I can't get the attached project to open...

i have tried several time but no zip file download can you send it to me?

I spent a lot of time to solve this issue. I tried every proposed solution on the web. None of them gave me the result i needed. I ended up calculating the height via a Script (MonoBehavior).

My aim was to calculate a 2D RectTransform (ScrollContent) that has children populated dynamically using the start() so the script executes once on update() after all has been initialized.

I added this to all the component with dynamic height and the scroll content.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScrollExpander : MonoBehaviour {

	private bool _updated = false;
	// Use this for initialization
	void Update () {

		if (!_updated) {
			RectTransform rectTransform = (RectTransform)transform;
			float yMin = 0.0f;
			float yMax = 0.0f;
			foreach (RectTransform child in transform) {
				yMin = Mathf.Min (yMin, child.offsetMin.y);
				yMax = Mathf.Max (yMax, child.offsetMax.y);
			}

			float finalSize = yMax - yMin;
			rectTransform.sizeDelta = new Vector2 (rectTransform.sizeDelta.x, finalSize);
			_updated = true;
		}
	}

}

Hope this helps some with this problem.

Thank you. You solution is best!

97544-capture.png

  1. Create a scroll view (right click > UI > Scroll View)

  2. Select Content, add Content Size Fitter component.

  3. Change the settings of both Content Size Fitter and Rect Transform like in the image below.

  4. Through your own script add text to Text component (dynamically).

    Text myText = this.transform.GetComponent();
    myText.text += “your desired text”;

You're example won't work properly without the addition of a VerticalLayoutGroup to the Content object. You would also need to select Control Child Size Height on the VerticalLayoutGroup to make the Text component and Content area automatically resize to fit the text.

This worked perfectly as is in your example, thanks so much for posting this!

Even in Unity 2021.1.24f1 you still have to add the Content Size Fitter manually to the Content (weird that it doesn't do it by default) but then it changes size accordingly. If you want to add multiple elements, I'd also recommend adding a Vertical or Horizontal Layout Group to align them properly (default: Control Child Size/Child Force Expand: Width). Btw, if the Scroll View itself is part of a Layout Group, then you can add a "Layout Element" component to it and it won't interfere.

Think you need to add Component Content SizeFilter and set it to unrestrained

EDIT:

Well that’s what I get for not checking my own menu item. BoredMormon is right you have to set the RectTransform to dynamically increase in size with enough for each item that you include.

In my case that’s just vertical but it could be both.

See RectTransform.OffSetMax and RectTransform.OffSetMin

get the count of how many items are being loaded and multiply that by the how many times you’re going to increase the x and y.

Not written the code to fix mine yet but if you’re struggling I’ll post the solution when I have it.

You actually want to constrain it on the vertical. Also add layout elements to each button. Check out my UI tutorials for a [1]. It's not exactly what you are after, but you should be able to figure out all the pieces. [1]: http://www.youtube.com/watch?v=ANUDrfSBnoQ

Check out this video as well: [Unity 4.6 UI Menu][1] I added the demo unity package to it under CursedIsle username to show how to build menu items from a list. As I say on the YouTube comments virus check and open in a new project so I don't break anything you've done. It was virus free when it left me but I can't be 100% sure of that once it's on the web. Oh and follow both Stuart Spence and Richard Gubb on Youtube both well worth following. [1]: https://www.youtube.com/watch?v=TRLsmuYMs8Q

To create a dynamic list of objects I use Horisontal/Vertical Layout Group in combination with Aspect Ratio component.
In this case, I can on the fly change the screen orientation, resolution or add/remove elements - but interface will behave predictable anyway.

  1. Create a prefab of a list item and attach Aspect Ratio component, so that the object held their aspect.
  2. Create panel object - full list container. And attach two component:

a. Horisontal/Vertical Layout Group - this component will put items in order

b. Aspect Ratio - the component we’ll be changing through code, depending on the items count and their personal aspect ratio
(like - containerAspectRatio = itemAspectRation * (float) itemArray.Count; )

Maybe you guys find my answer a little bit helpful.

I was working on a similar thing, while I was searching for the resources I found this Unity Document very helpful.
link text

So basically what you have to do is:

  1. Add a layout group (Horizontal or Vertical/ Both depending on your requirement) to the UI element, This will work as the layout controller.
  2. Add Content Size Fitter.
    They communicate to adjust UI element Rect Transform. You can tweak your settings to get the desired output.

To summarize the correct answers…
There is a simple component called “Content Size Fitter” … you are welcome

After setting the content height, you also need to handle the scroll position. If you want to keep the % vertical scroll position the same, a solution is below. Add the script as component to the scene. Assign the scrollRect variable by drag and drop in editor. In your managing script, declare the scroll position class:


public ScrollRectVerticalPositionHolderOnContentHeightChange scrollHolder;

Then assign the script in editor by drag and drop. Whenever you update the content height of Scroll Rect, call the method ContentHeightUpdated()


using UnityEngine;
using System;
using UnityEngine.UI;
using System.Collections;

public class ScrollRectVerticalPositionHolderOnContentHeightChange: MonoBehaviour {
    public ScrollRect scrollRect;
    float lastVerticalScrollPosition;

    void Start() {
         scrollRect.onValueChanged.AddListener(TableScrolledEvent);
    }

     void TableScrolledEvent(Vector2 value)
    {
        lastVerticalScrollPosition = scrollRect.verticalNormalizedPosition;
    }

    public void ContentHeightUpdated() {
        StartCoroutine(SetVerticalPositionScroll());
    }

    IEnumerator SetVerticalPositionScroll()
    {
        // If you set the orderscontent port, the scroll position resets. To avoid this, the position is set in the frame after a change in content port height
        yield return 0;
        scrollRect.verticalNormalizedPosition = lastVerticalScrollPosition;
    }
}

You can check this link for dynamic scroll

Try calling

contentSizeFitter.SetLayoutVertical();

referencing the proper ContentSizeFitter component.

https://docs.unity3d.com/ScriptReference/UI.ContentSizeFitter.SetLayoutVertical.html

it states it’s called by the layout system, but seems like working me even if i call it manually to update the layout after modifications to it’s content.

Hope this helps.

vertical layout group shows the images like this.

but my requirement like this.
How can i achieve this