Search Unity

Superfluous elasticity on ScrollRects that don't need scrolling yet

Discussion in 'UGUI & TextMesh Pro' started by fschneider, Aug 24, 2016.

  1. fschneider

    fschneider

    Joined:
    May 26, 2014
    Posts:
    42
    I'm having a scroll view to display a list of items. When it is first presented, no scrolling is needed yet, as all items fit into the visible area.

    I have noticed that
    Code (CSharp):
    1. ScrollRect.MovementType.Elastic
    leads to the items being draggable (so that the view can flip back). That seems nonsensical as long as nothing needs to be scrolled yet.

    The only way that I can imagine to circumvent that behaviour, is to dynamically switch between movement types, e.g. enable the elasticity as soon as there is enough content in the view.

    Would be interested in ideas and feedback whether anybody had the same issue.
     
  2. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    If you create a Generic UI ScrollView and Uncheck the Horizontal and Vertical boxes directly above the Elastic Movement, then the user can't drag the list with the mouse, only by using the scroll bar. (Which you by default doesn't appear until the Content area is bigger than the scroll Rect. To make a Text list I would then add 2 Items to the Content Object of the ScrollView using Add Component (don't make them children)
    1. Text Component - Horizontal Overflow set to Wrap, Vertical OverFlow set to truncate
    2. Content Size Fitter with Vertical Fit set to Preferred Size.
    This will start your List with no Scrollbars and if it enough text is added it will popup the Vertical Scrollbar. If you wish the Horizontal scrollbar to be used change Horizontal Overflow to truncate, and Change the Content Size Fitter Horizontal fit from Unconstrained to Preferred Size as well.

    One thing to note the scrollbars stay where they are, they don't automatically move to the bottom. So if you add more text to a list it scrolls down below the screen and the user has to scroll down to it.. every time a new line is added they would have to scroll down (very annoying for a chat box). Here is a small C# script I wrote that has a public add text function other Objects can call, as well as keeping the scroll bar at the bottom (unless the user specifically scrolled up.. then it keeps it there).

    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.Event
    public class TextViewController : MonoBehaviour {

    private Scrollbar vScroll;
    private bool textAdded;
    private Text chatText;

    public void Start()
    {
    vScroll = GetComponentsInChildren<Scrollbar>()[1];
    vScroll.onValueChanged.AddListener(delegate { HandleVScroll(); });
    chatText = GetComponentInChildren<Text>();
    textAdded = false;
    }

    public void AddText(string text)
    {
    // check if the scroll bar was at the bottom
    // So we can reset it there. If not leave where it is.
    if (vScroll.value == 0)
    textAdded = true;
    //This assumes "\r\n" has been added by the Sender
    // You can add it yourself here to make sure each call is a newline.
    chatText.text += text;
    }

    public void ClearText()
    {
    chatText.text = "";
    }

    private void HandleVScroll()
    {
    if (textAdded)
    {
    vScroll.value = 0;
    textAdded = false;
    }
    }
    }
     
  3. fschneider

    fschneider

    Joined:
    May 26, 2014
    Posts:
    42
    I should have mentioned that I'm developing for mobile, and per UI design, we don't want to have a scrollbar...

    Which means I can't uncheck "Vertical".
     
  4. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Well I am assuming you are starting off with just a few items in the scroll list and you have some function to dynamically add more. Iniitally have the Vertical unchecked, so user can't scroll. Then every time you add a new item do the following:

    // You will need to use GetComponents to get these variables or
    // add them as public variables and set them in the editor.
    using UnityEngine.UI;

    if (content.rectTranForm.sizeDelta.y > viewport.rectTransform.sizeDelta.y )
    scrollRect.vertical = true;
    else
    scrollRect.vertical = false;

    This will check if your viewPort (which is static) is bigger/smaller than the Content (which should be growing and shrinking if you've added a Content Fitter component)
     
    fschneider likes this.
  5. fschneider

    fschneider

    Joined:
    May 26, 2014
    Posts:
    42
    You're right, that should do it :)