- Home /
Add scrollbar to multiline input field???
I'm trying to add a scrollbar to a multiline input field so the user can input a nice big block of text and be able to scroll through it without having to drag-select text to scroll (or use the arrow keys). I've tried everything I can think of, content size fitters, horizontal layout groups with content size fitters, nothing works. Here's my current layout that kind of works, but for some reason the text disappears into the vertical ether and I have to drag-select text to be able to see it all everytime I type something:
Answer by Dibbie · May 08, 2015 at 12:29 AM
I actually just figured this out using elements instead of text (for my uses), but itll work the same.
Create a new UI Panel
Size it to whatever youd like
Create a new UI Scrollbar
Place it wherever ud like, mess with the settings to your preferences
Create a new UI Text/Input Field/Whatever you want to use
On that new UI Text, add a "Scroll Rect" component (UI > Scroll Rect)
Set the "Content" to be WHAT you want to have scrolled, so if its a InputBox, you can use the Text child of that for example
Depending which way you want to scroll (I assume conventionally, so Vertical) set the Horizontal, Vertical, or both scroll bars to the scroll bar you created
Be sure to check the correct rotation of your scrollbar under the "Content", to be "Vertical" (in your case I assume, for conventional ways), or "Horizontal", or both, if you are using both directions
Mess with the other settings (mainly movement type and the settings that follow the selected type of movement) how youd like
Create some text that goes beyond the set boundaries defined at edit time (so write a bunch of text...), then use the scroll bar
It didnt work for me with scrolling using my mouse wheel, but it could be that I dont have it focused when I do it, you could always make a simple script that if the mouse is scrolled up or down, then just chance the value of the scrollbar by code with a simple += or -= 1 kind of thing.
Hope that works out for you.
Sorry, in addition to this, I also found one problem, and a solution to it... You may notice that if you type too much, it wont hide the text properly... If you add a "$$anonymous$$ask" component to the text, it should fix that.
thank you... I tried eahc step but it doesn't work for me. text doesn't scroll at all....
Answer by illa3d · Feb 09, 2017 at 02:04 PM
Posted a hacky solution to InputField with scrollbar here: http://answers.unity3d.com/questions/932607/putting-a-multiline-inputfield-in-a-scroll-rect.html
Answer by SweatyChair · Nov 05, 2018 at 06:36 AM
This is my modified version of InputFieldMod, removing the highlight and take into account for canvas scale, etc:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System.Collections;
namespace SweatyChair.UI
{
[ExecuteInEditMode]
[RequireComponent(typeof(InputField))]
public class InputFieldScroller : UIBehaviour
{
[Tooltip("The default row count in InputField, this will be ignored if a ScrollRect is assigned")]
[Range(1, 50)] [SerializeField] private int _minRowCount = 1;
[Tooltip("Scroll rect parent")]
[SerializeField] private ScrollRect _scrollRect = null;
private InputField _inputField;
private RectTransform _rectTransform;
// Layout
private LayoutElement _layoutElement;
private HorizontalOrVerticalLayoutGroup _parentLayoutGroup;
private Vector2 _scrollRectSize;
private float _canvasScaleFactor = 1;
protected override void Awake()
{
_inputField = GetComponent<InputField>();
_inputField.onValueChanged.AddListener(new UnityAction<string>(ResizeInput));
_rectTransform = GetComponent<RectTransform>();
CanvasScaler canvasScaler = GetComponentInParent<CanvasScaler>();
if (canvasScaler)
_canvasScaleFactor = canvasScaler.scaleFactor;
_layoutElement = GetComponent<LayoutElement>();
_parentLayoutGroup = transform.parent.GetComponent<HorizontalOrVerticalLayoutGroup>();
}
// Resize input field recttransform
private void ResizeInput()
{
ResizeInput(_inputField.text);
}
private void ResizeInput(string text)
{
// Current text settings
TextGenerationSettings settings = _inputField.textComponent.GetGenerationSettings(_inputField.textComponent.rectTransform.rect.size);
settings.generateOutOfBounds = false;
settings.scaleFactor = _canvasScaleFactor; // HACK: scale factor of settings not following the global scale factor... make sure it do
// Get text padding (min max vertical offset for size calculation)
float vecticalOffset = _inputField.placeholder.rectTransform.offsetMin.y - _inputField.placeholder.rectTransform.offsetMax.y;
// Preferred text rect height
float preferredHeight = (new TextGenerator().GetPreferredHeight(text, settings) / _canvasScaleFactor) + vecticalOffset + 10;
float minHeight;
// Default text rect height (fit to scroll parent or expand to fit text)
if (_scrollRect)
minHeight = _scrollRect.GetComponent<RectTransform>().rect.size.y;
else
minHeight = ((new TextGenerator().GetPreferredHeight("", settings) * _minRowCount) / _canvasScaleFactor) + vecticalOffset;
// Current text rect height
float currentHeight = _inputField.textComponent.rectTransform.rect.height;
// Force resize
if (Mathf.Abs(currentHeight - preferredHeight) > Mathf.Epsilon) {
float newHeight = Mathf.Max(preferredHeight, minHeight); // At least min height
if (_parentLayoutGroup && _layoutElement)
_layoutElement.preferredHeight = newHeight;
else
_rectTransform.sizeDelta = new Vector2(_rectTransform.rect.width, newHeight);
}
// Scroll to bottom if just added new line
if (gameObject.activeInHierarchy && _inputField.caretPosition == _inputField.text.Length && _inputField.text.Length > 0 && _inputField.text[_inputField.text.Length - 1] == '\n')
StartCoroutine(ScrollToBottomCoroutine());
}
// Update scroll rect position (after Layout was rebuilt)
private IEnumerator ScrollToBottomCoroutine()
{
yield return new WaitForEndOfFrame();
if (_scrollRect != null)
_scrollRect.verticalNormalizedPosition = 0;
}
}
}
Your answer
Follow this Question
Related Questions
Putting a multiline InputField in a Scroll Rect? 4 Answers
How to disable character movement while editing InputField? 1 Answer
In an Input Field, I want to remove the whole word, if my user deletes on character of it 1 Answer
InputField null refrence exception 1 Answer
NullReferenceException after passing InputField gameObject into EventSystem.SetSelectedGameObject() 1 Answer